如何在Swift中实现泛型转换初始化?(复制)

时间:2022-04-30 14:30:47

This question already has an answer here:

这个问题已经有了答案:

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 转换为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) }
}