如何在Swift generic where子句中添加OR条件?

时间:2018-06-10 10:12:33

标签: swift generics where

我正在使用带有数字的算术运算从Apple SceneKit扩展SCNVector3。我使用泛型作为数字类型,但我发现我必须至少编写每个函数的两个版本,因为这不起作用:

extension SCNVector3 {
    static func *<T> (left: SCNVector3, right: T) -> SCNVector3 {
        return SCNVector3(left.x * Float(right), left.y * Float(right), left.z * Float(right))
}

并给出错误无法使用类型为'(T)'的参数列表调用Type'Float'的初始值设定项

在Apple文档中查看Float的definition,我发现我能得到的最通用的是init<Source: BinaryFloatingPoint>init<Source: BinaryInteger>

所以我必须重写扩展如下,为每个操作创建两个几乎相同的函数:

extension SCNVector3 {
    static func *<T> (left: SCNVector3, right: T) -> SCNVector3 where T: BinaryFloatingPoint {
        return SCNVector3(left.x * Float(right), left.y * Float(right), left.z * Float(right))

    static func *<T> (left: SCNVector3, right: T) -> SCNVector3 where T: BinaryInteger {
        return SCNVector3(left.x * Float(right), left.y * Float(right), left.z * Float(right))
}

我可以在where子句中放置AND - 在where之后用逗号分隔两个条件。

但有什么方法可以放在那里吗?

1 个答案:

答案 0 :(得分:2)

您的基本实施应从此开始:

extension SCNVector3 {
    static func * (vector: SCNVector3, scale: Float) -> SCNVector3 {
        return SCNVector3(vector.x * scale, vector.y * scale, vector.z * scale)
    }
}

向量具有Float个组件,因此您应始终仅乘以Float。这就是Swift中所有运营商的工作方式。如果您有不同的类型,请在乘法之前进行投射,而不是乘法的副作用。

如果确实想要传递其他类型,那么您可以使用方法重载:

extension SCNVector3 {
    static func *<T> (left: SCNVector3, right: T) -> SCNVector3 where T: BinaryFloatingPoint {
        return left * Float(right)
    }

    static func *<T> (left: SCNVector3, right: T) -> SCNVector3 where T: BinaryInteger {
        return left * Float(right)
    }
}

无法在类型中定义