【问题标题】:How do I create an instance of a class from the child of a Mirror object in Swift如何从 Swift 中的 Mirror 对象的子对象创建类的实例
【发布时间】:2017-10-03 18:36:27
【问题描述】:

我试图理解为什么我无法在 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()

带有“typeClone2”的行是失败的行。如果我分解表达式并检查事物,似乎所有类型和值都是相似的,如第一个示例所示。但在第二种情况下,操场会发出此错误:

游乐场执行失败:

error: Type Playground.playground:12:18: error: 'init' is a member of the >type;使用 'type(of: ...)' 来初始化相同动态 >type 的新对象 var typeClone2 = type( of: tMirror.children.first!.value ).init() ^ 类型(属于:)

我必须做些什么才能完成这项工作?提前致谢!

【问题讨论】:

    标签: swift dynamic reflection types mirror


    【解决方案1】:

    您的代码不起作用,但您得到的错误是错误的,因此您应该忽略它。

    真正的问题是你不能盲目地在Any 的类型上调用init()。有很多类型根本没有init()。它适用于您的第一个示例中的type(of: s),因为编译器在编译时知道该类型是String(并且String 具有init())。但是如果你将它包装在Any 中,那么它也会失败:

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

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

    【讨论】:

    • 谢谢。我接受了答案,因为它清楚地详细说明了代码不起作用的原因。是否有另一种在运行时提取类型信息的替代方法,以便我可以创建类似类型的对象,对其进行操作,然后将其作为 Any 再次存储在某个地方?再次感谢。
    • 唯一的方法是声明一个协议,定义适当的方法来执行任何你想要的复制+操作,然后在你希望能够操作的所有类型上采用该协议。
    猜你喜欢
    • 2015-11-17
    • 2015-01-22
    • 2020-06-18
    • 2014-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多