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
您不需要 reflection
和 AableError
。
首先让我们添加一个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
我的示例包括:
- 具有只读属性的协议
- 实现该协议的结构
- “+”运算符函数
我希望“+”运算符能够适用于协议的所有实现 通过创建实现该协议的特定类型的 新实例。
正如您在下面的源代码中看到的,运算符接受类型为 "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
您不需要 reflection
和 AableError
。
首先让我们添加一个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