快速反思:如何基于反射构造一个新的结构实例?

时间:2016-05-11 10:11:14

标签: swift reflection protocols

我的例子包括:

  • 具有只读属性的协议
  • 实现该协议的结构
  • " +"操作员功能

我喜欢" +"通过创建特定类型的新实例运营商能够适用于协议的所有实施实现该协议。

正如您在下面的源代码中所看到的,操作员接受类型" 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

1 个答案:

答案 0 :(得分:3)

您不需要reflectionAableError

首先,我们可以为您的协议添加init

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

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

  • 这两个参数符合协议Aable
  • params具有相同的类型
  • 返回类型与参数
  • 相同

您可以使用泛型

定义此约束
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