如何在Swift中从Mirror对象的子对象创建类的示例

6ljaweal  于 2023-06-21  发布在  Swift
关注(0)|答案(2)|浏览(103)

我试图理解为什么我无法在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:)
我该怎么做才能成功?先谢谢你了!

zzwlnbp8

zzwlnbp81#

你的代码不会工作,但你得到的错误是错误的,所以你应该忽略它。
真正的问题是,您不能盲目地在Any类型上调用init()。有很多类型根本没有init()。在第一个示例中,它适用于type(of: s),因为编译器在编译时知道该类型是String(并且String具有init())。但是如果你把它 Package 在Any中,那么它也会失败:

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

不幸的是,这意味着没有办法做你想做的事情。

1tuwyuhd

1tuwyuhd2#

我为子孙后代加上这个。我知道这是一个老问题了,但在最近的版本中,我们现在有一种方法来实现这一点。
一个伟大的来源,解释了整个事情是在这里:https://www.pointfree.co/blog/posts/78-reverse-engineering-swiftui-s-navigationpath-codability
但为了保存读取器,_typeByName("")将类型返回为Any
注意它的不是私有API-它是内部的(注意下划线),所以不鼓励使用,但通常是安全的,也是常用的(包括)。

相关问题