要求方法参数的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
? 而你如何为animals
arrays声明?
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