我在xCode中尝试过这段代码:let bigNum = Int8.max Int(“1”)!编译器推断Int8类型的变量bigNum并给出溢出错误. 对于Int8.max Int(“1”)!:“”的左侧具有Int8的类型,右侧具有Int的类型.为什么编
对于Int8.max Int(“1”)!:“”的左侧具有Int8的类型,右侧具有Int的类型.为什么编译器没有将bigNum推断为Int的类型?
猜测:Swift的编译器总是通过更窄/受限制的值类型推断tye,因为Int8是一个比Int更小和更窄的类型,因此添加Int8和Int数将导致Int8类型推断.
问题:我是对的吗?或大多数是正确但不精确.如果是这样,请纠正我.
谢谢
类型推理引擎不知道Ints的位宽.它甚至不知道Ints是数字.引擎对类型实现的“限制性”或“狭窄性”一无所知.它只知道类型如何作为超类型和子类型(“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选择的函数的最好方法是选择 – 单击符号.它会告诉你它正在使用什么类型.