要求方法参数的types和协议

我正在玩Swift,正在绊倒以下问题:由于我有预定义的类Animal

 //Predefined classes class Animal { var height: Float = 0.0 } 

我现在用接受动物的构造函数编写类Zoo 。 但Zoo希望每个动物都有一个名字,因此定义了Namable协议。

 protocol Namable { var name: String {get} } class Zoo { var animals: Animal[] = []; } 

你将如何编写一个addAnimal方法,要求作为parameter passing的对象既是Animal types ,也符合协议 Namable ? 而你如何为animalsarrays声明?

  func addAnimal:(animal: ????) { ... } 

在Objective-C中,我会写这样的东西

  - (void)addAnimal:(Animal<Namable>*)animal {...} 

您可以使用具有多个条件的where子句的generics。

 func addAnimal<T: Animal where T: Nameable>(animal: T) { ... } 

修正:你应该使整个类通用,所以你可以正确地键入数组

 class Zoo<T: Animal where T: Nameable> { var animals : T[] = [] func addAnimal(a: T) { ... } } 

对我来说,这似乎更多的是一个架构问题:

Nameable是一个奇怪的协议。 从逻辑上讲,每只动物都有能力被命名,所以Animal应该始终遵守Nameable

当动物没有被命名时,允许没有名字,而不是动物可以有名字,而动物不能命名,这将是非常简单的。

然后你可以通过一个assert强制执行Zoo名字。

在Objective-C中:符合协议

在Swift中是generics的

您可以使用where关键字来做更多的事情

使用types名称之后的位置来指定需求列表(例如,要求types实现协议),要求两种types相同,或要求类具有特定的超类。

摘录自:苹果公司“Swift编程语言”, iBooks 。

Swift 3版本

在Swift 3中,结构发生了一些变化。 这就是为什么你会得到旧结构的弃用警告。 这是新的:

对于函数,期望的协议位于函数的参数定义之后。 例:

 func addAnimal<T: Animal>(animal: T) where T: Nameable 

对于枚举或类,结构也发生了变化

 enum ZooEnum<T: Animal> where T: Nameable class Zoo<T: Animal> where T: Nameable