swift 反射:如何根据反射构造新的结构体实例?

swift reflections: how to construct a new struct instance based on reflections?

我的示例包括:

我希望“+”运算符能够适用于协议的所有实现 通过创建实现该协议的特定类型的 新实例

正如您在下面的源代码中看到的,运算符接受类型为 "Aable" 的参数(协议)。使用 通用占位符 T 构造新实例失败并出现错误“'Aable' 无法构造,因为它没有可访问的初始值设定项”。

这可能吗?

是否可以使用反射或某种内省来实现?

protocol Aable {
    var name: String { get }
}

func +(left: Aable, right: Aable) -> Aable {
    let leftType = left.dynamicType
    //error: 'Aable' cannot be constructed because 
    //       it has no accessible initializers
    return leftType(name: left.name + right.name)
}

struct A: Aable {
    let name: String
}

let a1 = A(name: "A #1")
let a2 = A(name: "A #2")

a1 + a2

您不需要 reflectionAableError

首先让我们添加一个init到你的协议

protocol Aable {
    var name: String { get }
    init(name:String)
}

现在您需要一个 + 运算符,其中:

  • 两个参数都符合协议Aable
  • 参数类型相同
  • return 类型与参数相同

您可以使用泛型定义此约束

func +<T:Aable>(left: T, right: T) -> T {
    return T(name:left.name + right.name)
}

现在检查是在编译时执行的,所以不需要 throws。编译器将确保使用的值具有正确的类型。

测试 #1

struct Box:Aable {
    let name:String
}

let amazon = Box(name: "Amazon")
let apple = Box(name: "Apple")
let res = amazon + apple
res.name // "AmazonApple"

测试 #2

struct Box:Aable {
    let name:String
}

struct Box:Aable {
    let name:String
}

struct Bottle:Aable {
    let name:String
}

let box = Box(name: "Amazon")
let bottle = Bottle(name: "Water")
box + bottle
//  ^ compile error