我有这段编译得很好的 Swift 代码:
let someArray = Array(count: 45, repeatedValue: 0)
let a: UIntMax = 0x00010000
let b = a + someArray.count
let c = (b + 0x1000 - 1) / 0x1000
println("\(someArray.count == c), \(c)")
但是,我认为如果我确保在将 - 1 添加到 b< 之前将其应用于 (第 4 行),所以我想将其更改为:0x1000,则溢出的可能性会稍微降低一点
let c = (b + (0x1000 - 1)) / 0x1000
令人惊讶的是,该片段不再编译。我在 println 行收到此错误:
Could not find member
convertFromStringInterpolationSegment
发生了什么事?为什么带括号的表达式的行为与未带括号的表达式有任何不同,为什么会产生影响?
请您参考如下方法:
很奇怪。添加这些括号将 c 的类型推断从 Int 更改为 UInt64。这会导致最后一行出错,因为 someArray.count 是一个 Int,您无法比较不同的类型。
我会 (a) 提交错误报告并 (b) 分解表达式。
多看了几眼,现在我想知道为什么第一个版本可以编译。一行一行:
让一个:UIntMax = 0x00010000a是UInt64类型。 (UIntMax只是一个类型别名。)让 b = a + someArray.countb也是UInt64类型。 “等等,”你说,“你说过你不能添加UInt64和Int实例!”在这种情况下,正在使用的+运算符是这个:func +<T : Strideable>(lhs: T, rhs: T.Stride) -> T本例中的
UInt64实例是 strideable 值,Int实例与其Stride匹配。令 c = (b + 0x1000 - 1)/0x1000先看括号内的子表达式,
+和-的结合性意味着这等价于((b + 0x1000) - 1)。此处编译器选择的+运算符是UInt64的标准运算符,但是-运算符是一个采用两个Strideable值并返回它们的Stride:func -<T : Strideable>(lhs: T, rhs: T) -> T.Stride这导致整个子表达式的类型为
Int而不是UInt64,因此c也是一个Int.
我认为编译器错误发生在选择 - 运算符重载时,因为没有理由不继续将事物评估为 UInt64。
