我试图理解为什么我无法在Swift中使用镜像创建类的示例。在操场上,一切似乎都很好,直到下面的最后一行代码。
下面是使用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)
一切都按预期进行。现在,当我试着对一个在镜子里发现的孩子做同样的事情时,操场抱怨说:
// 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()
带有“typeClone 2”的行是失败的行。如果我分解表达式并进行检查,似乎所有的类型和值都是相似的,就像第一个例子一样。但在第二种情况下,playground发出以下错误:
Playground执行失败:
错误:类型Playground.playground:12:18:错误:'init'是>类型的成员; use 'type(of:...)'来初始化相同dynamic >type的新对象var typeClone 2 = type(of:t儿童先照镜子!.value).init()^ type(of:)
我该怎么做才能成功?先谢谢你了!
2条答案
按热度按时间zzwlnbp81#
你的代码不会工作,但你得到的错误是错误的,所以你应该忽略它。
真正的问题是,您不能盲目地在
Any
类型上调用init()
。有很多类型根本没有init()
。在第一个示例中,它适用于type(of: s)
,因为编译器在编译时知道该类型是String
(并且String
具有init()
)。但是如果你把它 Package 在Any
中,那么它也会失败:不幸的是,这意味着没有办法做你想做的事情。
1tuwyuhd2#
我为子孙后代加上这个。我知道这是一个老问题了,但在最近的版本中,我们现在有一种方法来实现这一点。
一个伟大的来源,解释了整个事情是在这里:https://www.pointfree.co/blog/posts/78-reverse-engineering-swiftui-s-navigationpath-codability
但为了保存读取器,
_typeByName("")
将类型返回为Any
注意它的不是私有API-它是内部的(注意下划线),所以不鼓励使用,但通常是安全的,也是常用的(包括)。