在泛型函数内部转换泛型类似乎改变了类型参数的推断

时间:2014-11-15 00:45:10

标签: class generics swift metaclass type-parameter

我有一种奇怪的情况,通过将泛型函数中的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调用FooBar都可以推断为f,但我认为在两种情况下都可以推断出T.self同样的事情,因为类型参数的推断应仅在签名和调用代码上进行,签名和调用代码在两种情况下都是相同的。

T.Type应该已经是{{1}}类型,因此强制转换它应该是一个无操作(实际上,编译器甚至不应该允许转换,因为它应该总是为真)。然而,通过执行此演员,我似乎正在改变我正在调用初始化器的类。如果对象成功,则转换对象不应该改变对象的值,所以这真的很奇怪。

1 个答案:

答案 0 :(得分:0)

现在有一个thread on this in the dev forums。最相关的位基本上指向这是Swift的参数类型系统的结果:

  

Swift的类型系统是参数化的,这意味着泛型函数或类型的行为与其泛型类型参数相同,而不是像C ++那样基于替换。 [...]在像Swift这样的参数化系统中,通用函数只需要进行一次类型检查和编译,因为每种类型的行为都不会改变,并且可以跨编译单元边界使用泛型。

在那个帖子中有更多的探索和解释。