对类型推断背后机制的猜测

A guess for a mechanism behind Type Inference

我在 xCode 中试过这段代码: let bigNum = Int8.max + Int("1")! 编译器推断 bigNum 类型的变量 Int8 并给我溢出错误。

对于Int8.max + Int("1")!"+"左边的类型是Int8右边的类型是Int .为什么编译器没有将 bigNum 推断为 Int 的类型?

猜测:Swift的编译器总是通过更多的narrow/restricted值类型来推断类型,因为Int8是一个更小的和窄类型相比 Int,因此添加 Int8Int 数字将导致 Int8 类型推断。

问题:我说的对吗?或大部分正确但不准确。如果是,请指正。

谢谢

类型推理引擎不知道 Int 的位宽。它甚至不知道 Int 是数字。引擎对 "restrictedness" 或 "narrowness" 类型的实现方式一无所知。它只知道类型如何作为超类型和子类型相互关联("ISA" 关系),并尝试通过弄清楚它可以插入您提供的类型变量中的内容来解决约束问题。

类型推理引擎的选择基于所选择的 + 版本。 None 的基于 Int 的 + 函数适用。它们都是以下形式:

public func +(lhs: Int8, rhs: Int8) -> Int8

而且它的两边都没有 Int8。所以它选择它能找到的下一个最具体的:

public func +<T : Strideable>(lhs: T, rhs: T.Stride) -> T

为什么是这个? Int8SignedIntegerSignedInteger 以这种方式实现 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
}

通过类型推断,我们看到 StrideInt。所以我们的函数是:

public func +(lhs: Int8, rhs: Int) -> Int8

当然会在运行时溢出。

顺便说一句,找出 Swift 选择的函数的最佳方法是按住 Option 键并单击 + 符号。它会告诉您它使用的是什么类型。