如何在Swift中实现泛型转换初始化器?
问题描述:
我执行斯威夫特二维矢量结构:如何在Swift中实现泛型转换初始化器?
public struct Vec2<T: Numeric> {
public let x: T
public let y: T
public init(_ x: T, _ y: T) {
self.x = x;
self.y = y;
}
// ...
}
public protocol Numeric: Equatable {
// ...
}
extension Int: Numeric {}
extension Double: Numeric {}
extension Float: Numeric {}
此代码编译。现在我想添加一个转换初始化程序以允许转换例如Vec2<Int>
至Vec2<Float>
。我说这Vec2
:
public init<T2: Numeric>(_ other: Vec2<T2>) {
self.x = T(other.x)
self.y = T(other.y)
}
和所需初始化到Numeric
协议:
init(_: Int)
init(_: Double)
init(_: Float)
然而,这引起我是无法解决的错误:
不能使用类型为'(T2)'的参数列表调用类型为'T'的初始化程序
overloop这些部分匹配的参数列表存在'T'的广告:(Int),(Double),(Float)
任何想法?
答
_asOther
'影子'功能解决方案出现here工作。万一任何人的兴趣,这里的最终代码:
public struct Vec2<T: Numeric> {
public let x: T
public let y: T
public init(_ x: T, _ y: T) {
self.x = x;
self.y = y;
}
public init<T2: Numeric>(_ other: Vec2<T2>) {
self.x = other.x._asOther()
self.y = other.y._asOther()
}
// ...
}
public protocol Numeric: Equatable {
init(_: Int)
init(_: Double)
init(_: Float)
func _asOther<T: Numeric>() -> T
// ...
}
extension Int: Numeric {
public func _asOther<T: Numeric>() -> T { return T(self) }
}
extension Double: Numeric {
public func _asOther<T: Numeric>() -> T { return T(self) }
}
extension Float: Numeric {
public func _asOther<T: Numeric>() -> T { return T(self) }
}
的问题(对欺骗问题略有不同,但我不知道它值得一个单独的答案)是你的协议不能保证每一个具体类型符合'Numeric'由您在要求中列出的初始者处理。因此,你必须做一些事情来为协议添加一个'影子'功能要求,以保证每一种类型都实现自己的转换逻辑 - 我在回答上述链接问题时详细说明了这一点。 – Hamish
@ originaluser2谢谢,解决了它! – emlai
高兴地帮助:) – Hamish