【问题标题】:How to add OR condition in Swift generic where clause?如何在 Swift 通用 where 子句中添加 OR 条件?
【发布时间】:2018-06-10 18:50:22
【问题描述】:

我正在从 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)”的参数列表调用类型“Float”的初始化程序

查看 Apple 文档中 Float 的 definition,我发现我能得到的最通用的是 init&lt;Source: BinaryFloatingPoint&gt;init&lt;Source: BinaryInteger&gt;

所以我必须重写扩展如下,为每个操作制作两个几乎相同的功能:

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

我可以将 AND 放在 where 子句中 — 通过在 where 后面添加两个条件,用逗号分隔。

但是有什么方法可以放置 OR 那里吗?

【问题讨论】:

  • 从技术上讲,您应该只有一个函数采用Float,让函数的调用者正确转换。启用使用DoubleUInt 调用函数只是为了将值转换为Float 是没有意义的,可能会截断精度。

标签: swift generics where


【解决方案1】:

你的基本实现应该从这个开始:

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

没有办法在类型中定义

【讨论】:

  • 实际上我找到了方法——使用T: NSNumber——但决定坚持调用者应该将其参数转换为Float的想法。
  • 注意:SCNVector3 在 iOS 上具有 Float 组件,但在 macOS 上具有 Double 组件 (技术上,CGFloat 组件,其类型别名在 macOS 上为 Double 64 位 CPU).
猜你喜欢
  • 2019-12-28
  • 2019-06-26
  • 2016-12-16
  • 2012-07-26
  • 2013-12-23
  • 2021-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多