FloatingPoint协议中的文字数字

时间:2017-12-29 10:31:39

标签: swift generics

假期没什么可做的,我终于更新了我的数学库以使用FloatingPoint协议,并摆脱所有重复的代码。令我惊讶的是,我被字面数字直接咬了一下:

func uprightAngle1<T: FloatingPoint>(_ x: T) -> T {
    if (x > 0.5 * T.pi) && (x < 1.5 * T.pi) { // *** ERROR HERE
        // binary operator '*' cannot be applied to operands of type 'Double' and 'T'
        return x - T.pi
    } else {
        return x
    }
}

然而,这个工作正常:

func uprightAngle2<T: FloatingPoint>(_ x: T) -> T {
    if (x > T.pi / 2) && (x < 3 * T.pi / 2) { // All fine here
        return x - T.pi
    } else {
        return x
    }
}

任何人都可以

A)解释为什么编译器使用整数文字正确推断类型,但没有浮点文字,

B)向我展示当我不能使用有效性时使用的成语,因为let half: T = 0.5T(0.5)都没有编译......

1 个答案:

答案 0 :(得分:3)

FloatingPoint协议继承自ExpressibleByIntegerLiteral 通过继承链

FloatingPoint - SignedNumeric - Numeric - ExpressibleByIntegerLiteral

这就是第二个函数uprightAngle2编译的原因:值 类型T的类型是从整数文字23创建的。

第一个函数uprightAngle1无法编译,因为 FloatingPoint协议ExpressibleByFloatLiteral继承,即类型T的值不能 从像1.5这样的浮点文字创建。

可能的解决方案:

  • 将合理值创建为let half: T = 1/2。 ( let half = T(1/2), 这会在创建T之前截断分割结果 值。)

  • FloatingPoint替换为BinaryFloatingPoint(继承 来自ExpressibleByFloatLiteral)。

有关浮点设计的更多信息 协议见SE-0067 Enhanced Floating Point Protocols

Swift标准库中的浮点类型(DoubleFloatCGFloatFloat80)以及 来自Core Graphics框架的CGFloat都符合 BinaryFloatingPoint协议,因此该协议“足够 通用“适用于许多应用程序。