【发布时间】:2023-03-12 21:38:01
【问题描述】:
如果我理解正确的话,Swift 可以通过不同的方式确定泛型的实际类型,包括通过返回类型进行匹配。相同(或类似)的机制用于消除重载函数的歧义。所以这可以按预期工作:
func getValue<T>()->T? {
return nil
}
func getValue()->Int? {
return 13
}
let b: Int? = getValue()
运行时,b 将是13。从技术上讲,这两个函数签名都是合适的,但后者更具体到请求的返回类型。
让我们添加第二个函数并通过它隧道调用:
func getGetValue<T>()->T? {
return getValue()
}
let c: Int? = getGetValue()
运行时,c 将为nil。事实上,编译器会选择从getGetValue()中调用的通用getValue()实现,这不是我想要的。恕我直言,在 getValue() 的两个实现之间进行选择时,请求的返回类型应该通过第二个泛型传播,从而导致与第一个示例相同的行为。
我错过了什么? (Xcode 7.1)
【问题讨论】:
-
很好的发现。我的猜测是,当有另一层抽象时,按返回类型推断不起作用。一旦进入
getGetValue,编译器就不知道T是什么类型,所以第一个函数是唯一匹配的。 -
@ZoffDino 这也是我的猜测,但我不明白为什么编译器不能自下而上传播类型。从我的角度来看,它看起来像一个错误 - 但我不是编译器专家。也许这种行为有一个完全正当的理由。我会归档雷达,以防万一。
-
在 Swift 博客Memory Safety: Ensuring Values are Defined Before Use 中有一篇文章讨论了编译器在多大程度上证明了程序的正确性。我认为这与您的问题有些相关