我已经在 xCode 中试过这段代码:let bigNum = Int8.max + Int("1")!
编译器推断类型为 Int8
的变量 bigNum并给我一个溢出错误。
对于 Int8.max + Int("1")!
: "+" 左侧的类型为 Int8
右侧的类型为 Int
.为什么编译器没有将 bigNum 推断为 Int
的类型?
猜测:Swift 的编译器总是通过更窄/受限的值类型来推断类型,因为 Int8
与 Int
相比,它是一种更小更窄的类型,因此添加一个 Int8
和一个 Int
数字会导致 Int8
类型推断。
问题:我说得对吗?或大部分正确但不准确。如果是这样,请纠正我。
谢谢
最佳答案
类型推断引擎不知道 Int 的位宽。它甚至不知道 Int 是数字。引擎对类型实现方式的“限制性”或“狭窄性”一无所知。它只知道类型作为父类(super class)型和子类型(“ISA”关系)如何相互关联,并尝试通过弄清楚它可以插入您提供的类型变量的内容来解决约束问题。
类型推理引擎的选择基于所选的 +
版本。基于 Int 的 +
函数均不适用。它们都是以下形式:
public func +(lhs: Int8, rhs: Int8) -> Int8
而且它的两边都没有 Int8
。因此它会选择它能找到的下一个最具体的:
public func +<T : Strideable>(lhs: T, rhs: T.Stride) -> T
为什么是这个? Int8
是一个 SignedInteger
。 SignedInteger
以这种方式实现 Strideable
:
public protocol Strideable : Comparable {
associatedtype Stride : SignedNumber
public func distance(to other: Self) -> Self.Stride
public func advanced(by n: Self.Stride) -> Self
}
extension SignedInteger {
public func distance(to other: Self) -> Int
public func advanced(by n: Int) -> Self
}
通过类型推断,我们看到 Stride
是 Int
。所以我们的功能是:
public func +(lhs: Int8, rhs: Int) -> Int8
这当然会在运行时溢出。
顺便说一句,找出 Swift 选择的函数的最佳方法是按住 Option 键并单击 +
符号。它会告诉您它使用的是什么类型。
关于swift - 对类型推断背后机制的猜测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38805320/