【问题标题】:why is unresolved generic type legal in a generic?为什么泛型中未解析的泛型类型是合法的?
【发布时间】:2021-03-24 18:43:22
【问题描述】:

也许我太密集了,我意识到我应该知道这种事情,但我对此感到惊讶:

class Wrapper<T> {
    let value: T
    var wrapper: Wrapper? // ok
    init(value: T) {
        self.value = value
    }
}
class Thing {
    var wrapper: Wrapper? // error
}

错误是在类 Thing 中,我必须在声明类型时解析 Wrapper 泛型;例如,我需要说,

var wrapper: Wrapper<String>?

为什么声明一个属性在 Wrapper 内部具有简单且简单的 Wrapper 类型是合法的,而在其他地方则不然?是什么让 Wrapper 中的声明没问题?是不是因为编译器只是假设在 Wrapper 内部,Wrapper 意味着 Wrapper&lt;T&gt;

【问题讨论】:

  • @Jessy 我想我知道extension 位,但这似乎有所不同。
  • 在大多数情况下,它已经过时了。 forums.swift.org/t/…
  • 经过多次编辑,我想我已经将我的答案提炼成可以理解但不会太长的东西。抱歉,如果您在我重新编辑了很多次时尝试阅读它。我应该离线写的。
  • @ChipJarred Nah,我做同样的事情:回答然后疯狂地编辑。基本上你是说我的猜测是正确的;它推断T是同一个T。有趣的是我以前从未注意到这个快捷方式。

标签: swift generics


【解决方案1】:

Wrapper 的情况下,T 是已知的,因为它是 Wrapper 定义的一部分,所以在没有专门化的情况下使用 Wrapper 被隐式假定为 Wrapper&lt;T&gt;

Thing 的情况下,没有定义T,即使有,它也不会与Wrapper 中的T 相同。认为它类似于这些函数:

func foo(_ x: Int) {
   // x is known here
}

func bar() {
   // x is unheard of here.
}

func foobar(_ x: Int) {
   // x is known here, but it's not the same x as in foo
}

当然不同的是,即使foo 也必须明确引用x,而Wrapper 可以在其自己的定义中推断T。事实上,如果Wrapper 想要引用另一个专门针对不同类型的Wrapper,则必须明确说明:

class Wrapper<T> {
   ...
   func someConversion<U>(otherWrapper: Wrapper<U>) {
   }
}

另一方面,ThingWrapper 之外声明,因此它不知道T。所以从它的角度来看

var wrapper: Wrapper?

一样毫无意义
var values: Array?

如果编译器不知道Element 类型,则它无法创建数组。它也不能在不知道T 是什么的情况下创建您的Wrapper

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 2010-09-23
    • 2021-12-01
    相关资源
    最近更新 更多