泛型的意义在于允许我们的类具有多种不同的类型。我们可以指定我们的泛型有一些特定的方面。
例如,如果我们想要相等的对象,我们将在声明我们的泛型时指定:
class Foo<T: Equatable> {
}
或者也许我们想要属于 Bar 类或其子类之一的对象:
class Foo<T: Bar> {
}
使用类这样做的好处是我们仍然可以区分Foo<ParentClass> 和Foo<ChildClass> 的实例。如果我们不使用泛型,并指定类型为ParentClass 的实例变量,继承将允许我们仍将ChildClass 的对象分配给它,但我们将无法比较Foo 的对象来确定Foo 是什么类型,除非我们使用泛型。考虑一个[ParentClass] 类型的数组,它可以保存ParentClass 或其子类,而一个[ChildClass] 类型的数组,它不能保存ParentClass 类型的对象。
现在,回到Foo<T: String> 的问题,这里的问题是String 是一个结构。它不是可以继承的类,也不是其他东西可以遵循的协议。这是一个结构。 Foo 的唯一类型是 Foo<String>,因为没有其他类型是 String。因此,Foo<T: String> 是不允许的,因为它只会令人困惑。
将此与Foo<T: Equatable> 的第一个示例进行比较,因为事物可以符合Equatable,所以我可以实例化多种类型的Foo:
let i = Foo<Int>()
let d = Foo<Double>()
let s = Foo<String>()
let c = Foo<Character>()
但如果Foo<T: String> 被允许,我唯一能实例化的是:
let s = Foo<String>()
而且我永远无法实例化任何其他类型的Foo,那有什么意义呢?