【ITニュース解説】Swift - Reflection with the Mirror API

2025年09月04日に「Dev.to」が公開したITニュース「Swift - Reflection with the Mirror API」について初心者にもわかりやすいように丁寧に解説しています。

作成日: 更新日:

ITニュース概要

SwiftのMirror APIは、実行時にオブジェクトの型やプロパティ情報を取得・分析する機能(リフレクション)を提供する。構造体やクラスのインスタンスを調べ、プロパティ名や値を動的に取得可能。`displayStyle`で型を、`subjectType`で型名を知る事ができる。`children`でプロパティと値にアクセスできる。ただし、リフレクションは直接アクセスより処理負荷が高いため、パフォーマンスが重要な箇所での多用は避けるべき。

出典: Swift - Reflection with the Mirror API | Dev.to公開日:

ITニュース解説

SwiftにおけるReflection(リフレクション)は、実行時にプログラム自身を調べたり、構造や挙動を分析・変更したりする機能のこと。リフレクションを利用することで、型に関する情報を実行時に取得できる。これは、プログラムが自分自身を観察・検査するようなものだと考えられる。

Swiftでのリフレクションは、Mirror APIを使って実現される。このAPIを使うことで、クラス、構造体、列挙型のインスタンスを調べ、その型やプロパティの値を調べることが可能となる。特に、動的な型や未知の型を扱う際に、正確な型が事前に分からなくてもインスタンスを調べることができるため便利。

Mirror APIを通じて、インスタンスのプロパティ(子要素と呼ばれる)にアクセスし、インスタンス内に格納された値を調べることができる。これは、複雑なデータ構造を扱う場合や、特定の型の内部構造を理解したい場合に特に役立つ。

ただし、Swiftのリフレクション機能を使う際には、パフォーマンスへの影響を考慮する必要がある。リフレクション処理は、通常、直接アクセスよりも多くの計算能力を必要とする。そのため、アプリケーションのパフォーマンスが重要な部分でリフレクションを多用することは推奨されない。

Mirror APIを使うと、Swiftオブジェクトに関する情報を実行時に取得できる。

Mirror APIを使い始めるには、まず例で使用する型を作成する必要がある。ここでは、Person構造体を作成する。

1struct Person {
2    var firstName: String
3    var lastName: String
4    var age: Int
5}

この構造体では、firstNamelastName(どちらも文字列型)と、age(整数型)の3つのプロパティを定義している。次に、このPerson型でMirror APIをどのように使うかを見ていく。

1let person = Person(firstName: "Jon", lastName: "Hoffman", age: 55)
2let mirror = Mirror(reflecting: person)

このコードでは、まずPerson型のインスタンスを作成する。次に、Personのインスタンスを使ってMirror型のインスタンスを作成する。このmirrorインスタンスを使って、personインスタンスのさまざまな属性にアクセスできるようになる。

mirrorインスタンスを使って、personインスタンスのdisplayStylesubjectTypeの値を見てみる。次のコードで表示できる。

1print("Display Style: \(mirror.displayStyle!)")
2print("Subject Type: \(mirror.subjectType)")

displayStyleは列挙型であり、次のケースを含む。

  • class
  • collection
  • dictionary
  • enum
  • optional
  • set
  • struct
  • tuple

このリストから、displayStyleはインスタンスの基になる型を示していることがわかる。

subjectTypeは型の名前。

このコードを実行すると、次の出力が表示される。

Display Style: Optional(Swift.Mirror.DisplayStyle.struct)
Subject Type: Person

Mirror APIは、インスタンスのプロパティを調べるためにも使うことができる。次に、その方法を示す。

1for (label, value) in mirror.children {
2    print("Property: \(label ?? "Unknown"), Value: \(value)")
3}

childrenプロパティには、インスタンスのプロパティとその値のリストが含まれている。このプロパティには、インスタンスの格納されたプロパティのみが含まれており、計算プロパティなどの他の要素はこのコレクションに含まれていないことに注意が必要。このコードの出力は次のようになる。

Property: firstName, Value: Jon
Property: lastName, Value: Hoffman
Property: age, Value: 55

このように、Mirror APIを使うことで、Swiftの構造体やクラスの内部構造を、実行時に柔軟に調べることができる。ただし、パフォーマンスへの影響を考慮し、必要に応じて適切に使用する必要がある。特に初心者の方は、リフレクションの仕組みを理解した上で、パフォーマンスが重要な箇所での利用は避けるように心がけると良い。