我有一种奇怪的情况,通过将泛型函数中的T.self
更改为T.self as T.Type
,它会改变代码的语义:
class Foo {
required init() {}
}
class Bar : Foo {
}
func f<T: Foo>(_:T) -> T {
return T.self()
}
println(f(Bar())) // prints MyProject.Foo
但
class Foo {
required init() {}
}
class Bar : Foo {
}
func f<T: Foo>(_:T) -> T {
return (T.self as T.Type)()
}
println(f(Bar())) // prints MyProject.Bar
这没有意义。该代码使用T.self
来创建T
类的实例。虽然在两种情况下T
调用Foo
或Bar
都可以推断为f
,但我认为在两种情况下都可以推断出T.self
同样的事情,因为类型参数的推断应仅在签名和调用代码上进行,签名和调用代码在两种情况下都是相同的。
T.Type
应该已经是{{1}}类型,因此强制转换它应该是一个无操作(实际上,编译器甚至不应该允许转换,因为它应该总是为真)。然而,通过执行此演员,我似乎正在改变我正在调用初始化器的类。如果对象成功,则转换对象不应该改变对象的值,所以这真的很奇怪。
答案 0 :(得分:0)
现在有一个thread on this in the dev forums。最相关的位基本上指向这是Swift的参数类型系统的结果:
Swift的类型系统是参数化的,这意味着泛型函数或类型的行为与其泛型类型参数相同,而不是像C ++那样基于替换。 [...]在像Swift这样的参数化系统中,通用函数只需要进行一次类型检查和编译,因为每种类型的行为都不会改变,并且可以跨编译单元边界使用泛型。
在那个帖子中有更多的探索和解释。