2014/09/22

Swiftでリフレクションを使ってみる

ドキュメントにないメソッドreflectを使えば、Swiftで一応リフレクションが使えるようなので使ってみました。

なお、ドキュメントには載っていない情報なので、今後変更されたり、なくなったりする可能性があります。

前提

次のようなクラスとインスタンスがあったとします。

struct Foo {
    let num = 3
    let str = "Hoge"
}

class Bar {
    let num = 3.14
    let str = "Fuga"
    let foo = Foo()
}

let x = Bar()

reflect

reflectを使うと識別子名や値などを見ることができます。

var ref = reflect(x)
for var i = 0; i < ref.count; ++i {
    let key      : String   = ref[i].0
    let summary  : String   = ref[i].1.summary
    let value    : Any      = ref[i].1.value
    let valueType: Any.Type = ref[i].1.valueType
    println("\(key) = \(value) \(valueType) \(summary)")
}

出力結果は次の通り。値の参照はできますが、代入はできないっぽいです。

num = 3.14 (ExistentialMetatype) 3.14
str = Fuga (ExistentialMetatype) Fuga
foo = SampleApp.Foo (ExistentialMetatype) SampleApp.Foo

デバッガで見ると_ClassMirrorという謎クラスが取れます。

dump

ちなみにドキュメントにないメソッドとしてdumpもあり、dump(x)で次のような出力を出します。

▿ SampleApp.Bar #0
  - num: 3.14
  - str: Fuga
  ▿ foo: SampleApp.Foo
    - num: 3
    - str: Hoge

関連情報

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。