I am trying to understand why I am unable to create an instance of a class using a mirror in Swift. In the playground, everything seems fine until the very last line of code below.
So, here's the first example with the use of type(of:):
// 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)
Everything works as expected. Now, when I try to do this same sort of thing with a child found in a mirror object, the playground complains:
// 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()
The line with "typeClone2" is the one that fails. If I break down the expressions and inspect things, it seems like all of the types and values are similar, as in the first example. But in the second case, the playground emits this error:
Playground execution failed:
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: )
What do I have to do to make this work? Thanks in advance!
Your code won't work but the error you get is wrong so you should ignore it.
The real problem is you can't just blindly call init()
on the type of an Any
. There are a lot of types that don't have an init()
at all. It works on type(of: s)
in your first example because the compiler knows at compile-time that the type is String
(and that String
has an init()
). But if you wrap it in Any
then it fails as well:
let s = String("Foo") as Any
let typeClone = type(of: s).init()
Unfortunately this means there's no way to do what you're trying to do.