为什么未解析的泛型类型在泛型中是合法的?

mat*_*att 7 generics swift

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

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

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

var wrapper: Wrapper<String>?
Run Code Online (Sandbox Code Playgroud)

为什么在 Wrapper 中声明一个属性具有 Wrapper 类型而不是其他地方是合法的?是什么让 Wrapper 内部的声明正常?是不是因为编译器只是假设在 Wrapper 内部,Wrapper意味着Wrapper<T>

Chi*_*red 4

在 , 的情况下WrapperT已知,因为它是Wrapper的定义的一部分,因此在没有专门化的情况下使用 被Wrapper隐式假定为Wrapper<T>

在 的情况下Thing,没有T定义,即使有,也不会T与 中的相同Wrapper。将其视为类似于以下函数:

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
}
Run Code Online (Sandbox Code Playgroud)

当然,区别在于,evenfoo必须显式引用x,而可以在其自己的定义内Wrapper推断。T事实上,如果Wrapper想要引用另一个Wrapper专门针对不同类型的对象,则必须明确说明:

class Wrapper<T> {
   ...
   func someConversion<U>(otherWrapper: Wrapper<U>) {
   }
}
Run Code Online (Sandbox Code Playgroud)

Thing另一方面是在 之外声明的Wrapper,所以它不知道T。所以从它的角度来看

var wrapper: Wrapper?
Run Code Online (Sandbox Code Playgroud)

就和一样毫无意义

var values: Array?
Run Code Online (Sandbox Code Playgroud)

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