假期没什么可做的,我终于更新了我的数学库以使用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.5
和T(0.5)
都没有编译......
答案 0 :(得分:3)
FloatingPoint
协议继承自ExpressibleByIntegerLiteral
通过继承链
FloatingPoint - SignedNumeric - Numeric - ExpressibleByIntegerLiteral
这就是第二个函数uprightAngle2
编译的原因:值
类型T
的类型是从整数文字2
和3
创建的。
第一个函数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标准库中的浮点类型(Double
,Float
,CGFloat
,Float80
)以及
来自Core Graphics框架的CGFloat
都符合
BinaryFloatingPoint
协议,因此该协议“足够
通用“适用于许多应用程序。