如何在Swift中实现泛型转换初始化器?

如何在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)

任何想法?

+0

的问题(对欺骗问题略有不同,但我不知道它值得一个单独的答案)是你的协议不能保证每一个具体类型符合'Numeric'由您在要求中列出的初始者处理。因此,你必须做一些事情来为协议添加一个'影子'功能要求,以保证每一种类型都实现自己的转换逻辑 - 我在回答上述链接问题时详细说明了这一点。 – Hamish

+0

@ originaluser2谢谢,解决了它! – emlai

+0

高兴地帮助:) – Hamish

_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) } 
}