如何在Swift中实现通用转换初始值设定项?

时间:2016-06-21 16:57:45

标签: swift generics type-conversion swift-protocols swift3

我在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 {}

此代码编译。现在我想添加一个转换初始化程序以允许转换,例如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)

但是,这会导致我无法解决的错误:

  

无法为类型&#39; T&#39;调用初始化程序。使用类型&#39;(T2)&#39;

的参数列表      

&#39; T&#39;过载存在这些部分匹配的参数列表:(Int),(Double),(Float)

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

_asOther&#39;影子&#39;提交的函数解决方案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) }
}