【问题标题】:Swift generic type selection does not propagateSwift 泛型类型选择不会传播
【发布时间】: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 中有一篇文章讨论了编译器在多大程度上证明了程序的正确性。我认为这与您的问题有些相关

标签: swift generics types


【解决方案1】:

你只是忘记投射了。

func getValue<T>()->T? {
    return nil
}

func getValue()->Int? {
    return 13
}

let b: Int? = getValue() // 13

func getGetValue<T>()->T? {
    return getValue() as? T
}

let c: Int? = getGetValue() // 13

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多