This question already has an answer here:
这个问题已经有了答案:
- How can I convert between related types through a common initializer? 1 answer
- 如何通过公共初始化器在相关类型之间进行转换?1回答
I'm implementing a 2D vector struct in Swift:
我在Swift中实现了一个2D矢量结构:
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 {}
This code compiles. Now I would like to add a conversion initializer to allow converting e.g. a Vec2<Int>
to a Vec2<Float>
. I added this to Vec2
:
这段代码编译。现在,我想添加一个转换初始化器,以允许将一个Vec2
public init<T2: Numeric>(_ other: Vec2<T2>) {
self.x = T(other.x)
self.y = T(other.y)
}
and the needed initializers to the Numeric
protocol:
以及数字协议所需的初始化程序:
init(_: Int)
init(_: Double)
init(_: Float)
However, this causes an error that I'm unable to solve:
然而,这导致了一个我无法解决的错误:
cannot invoke initializer for type 'T' with an argument list of type '(T2)'
不能使用类型为'(T2)'的参数列表调用类型为'T'的初始化器
overloads for 'T' exist with these partially matching parameter lists: (Int), (Double), (Float)
有这些部分匹配的参数列表:(Int)、(Double)、(Float)
Any ideas?
什么好主意吗?
1 个解决方案
#1
1
The _asOther
'shadow' function solution presented here worked. Just in case anyone's interested, here's the final code:
这里介绍的_asOther“影子”函数解决方案是有效的。以防有人感兴趣,这里是最后的代码:
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) }
}
#1
1
The _asOther
'shadow' function solution presented here worked. Just in case anyone's interested, here's the final code:
这里介绍的_asOther“影子”函数解决方案是有效的。以防有人感兴趣,这里是最后的代码:
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) }
}