2017-10-03 4 views
0

Swiftでミラーを使用してクラスのインスタンスを作成できない理由を理解しようとしています。プレイグラウンドでは、以下のコードの最後の行まですべてが正常に見えます。Swiftのミラーオブジェクトの子からクラスのインスタンスを作成するには

// First Example 
var s = String("Foo") // Playground Output: Foo 
type(of: s) // Playground Output: String.Type 
var typeClone = type(of: s).init() // Playground Output: "" (as expected) 

すべてが期待どおりに動作します:

だから、ここ:)のタイプの使用(との最初の例です。今、私はミラーオブジェクトで見つかった子供との事のこの同じ並べ替えを実行しようとするとき、遊び場は、不平を言う:

// Second Example 
class FooContainer { 
    var s : String = "Foo" 
} 

var t = FooContainer() 
var tMirror = Mirror(reflecting: t) // Output: Mirror for FooContainer 
tMirror.children.first! // Output: {some "s"}, value "Foo") 

type(of: tMirror.children.first!.value) // Output: String.Type 
var typeClone2 = type(of: tMirror.children.first!.value).init() 

「typeClone2」との行が失敗したものです。私が表現を分解して事を調べると、最初の例のように、すべての型と値が似ているようです。しかし、後者の場合には、遊び場は、このエラーを発する:

遊び場の実行に失敗しました:

error: Type Playground.playground:12:18: error: 'init' is a member of the >type; use 'type(of: ...)' to initialize a new object of the same dynamic >type var typeClone2 = type(of: tMirror.children.first!.value).init() ^ type(of: )

私はこの仕事をするためにしなければならないのですか?前もって感謝します!

答えて

0

コードは機能しませんが、エラーは間違っているため無視してください。

実際には、init()Anyのタイプで盲目的に電話することはできません。 init()を持たないタイプが多数あります。あなたの最初の例でtype(of: s)で動作します。なぜなら、コンパイラは、その型がStringであることを知っています(そしてStringinit()です)。しかし、あなたはAnyでそれを包む場合、それは同様に失敗します。

let s = String("Foo") as Any 
let typeClone = type(of: s).init() 

残念ながら、これはあなたが何をしようとして実行する方法はありませんを意味します。

+0

ありがとうございます。私はコードがうまくいかない理由をきれいに詳述しているので、答えを受け入れました。実行時に型情報を抽出する別の方法がありますか?同様の型のオブジェクトを作成して操作し、Anyとして再びどこかに隠すことができますか?再度、感謝します。 –

+0

これを行う唯一の方法は、何らかのコピー+操作を行い、操作できるようにしたいすべてのタイプでそのプロトコルを採用するための適切なメソッドを定義するプロトコルを宣言することです。 –

関連する問題