swift言語:Reflection APIを使ってみました
概要
swiftに含まれているReflection APIについて、The Swift Reflection API and what you can do with itを参考に、調べました。
ソースのコメントを見ると、PlaygroundやDebuggerなどで使うことが目的のようです。
$ cat ./stdlib/public/core/Mirror.swift
/// Mirrors are used by playgrounds and the debugger.
MirrorTypeも使えるようですが、使い方がわかりませんでした。
Reflection API
サンプルデータ
The Swift Reflection API and what you can do with itのサイトで説明に使っているデータです。
import Foundation.NSURL public class Store { let storesToDisk: Bool = true } public class BookmarkStore: Store { let itemCount: Int = 10 } public struct Bookmark { enum Group { case Tech case News } private let store = { return BookmarkStore() }() let title: String? let url: NSURL let keywords: [String] let group: Group } let aBookmark = Bookmark(title: "Appventure", url: NSURL(string: "appventure.me")!, keywords: ["Swift", "iOS", "OSX"], group: .Tech)
Mirror
Reflection APIを使うための最も簡単な方法は、Mirrorを作成することです。
// Mirror let aMirror = Mirror(reflecting: aBookmark) print(aMirror) // Mirror for Bookmark
「Mirror for Bookmark」が出力されます。これは以下のメソッド定義によります。
$ cat ./stdlib/public/core/Mirror.swift /// Reflection for `Mirror` itself. extension Mirror : CustomStringConvertible { public var description: String { return "Mirror for \(self.subjectType)" } }
Mirrorのメソッドは4つあります。
- Mirror.displayStyle
- Mirror.children
- Mirror.subjectType
- Mirror.superclassMirror:
Mirror.displayStyle
display styleを表示します。
print (aMirror.displayStyle)
Optional(Struct)が出力されます。データの型が出力されます。
public enum DisplayStyle { case Struct case Class case Enum case Tuple case Optional case Collection case Dictionary case Set }
Mirror.children
child要素を一覧します。
for case let (label?, value) in aMirror.children { print (label, value) }
Mirror.subjectType
型情報を出力します。
// subject type print(aMirror.subjectType) //prints : Bookmark print(Mirror(reflecting: 5).subjectType) //prints : Int print(Mirror(reflecting: "test").subjectType) //prints : String print(Mirror(reflecting: NSNull()).subjectType) //print : NSNull
Mirror.superclassMirror
スーパークラス情報を出力します。
// try our struct print(Mirror(reflecting: aBookmark).superclassMirror()) // prints: nil // try a class print(Mirror(reflecting: aBookmark.store).superclassMirror()) // prints: Optional(Mirror for Store)