也许我是非常密集,我意识到我应该知道这种事情,但我对此感到惊讶:
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>?
在 , 的情况下Wrapper,T已知,因为它是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是什么的情况下创造你。