我正在玩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
方法,要求将对象作为参数传递为类型 Animal
和符合协议 Namable
?那你如何为animals
数组声明呢?
func addAnimal:(animal: ????) { ... }
在Objective-C中,我写了这样的东西
- (void)addAnimal:(Animal<Namable>*)animal {...}
答案 0 :(得分:25)
您可以使用带有多个条件的where
子句的泛型。
func addAnimal<T: Animal where T: Nameable>(animal: T) { ... }
修正案:您可能应该使整个类成为通用类,以便您可以正确键入数组
class Zoo<T: Animal where T: Nameable> {
var animals : T[] = []
func addAnimal(a: T) {
...
}
}
答案 1 :(得分:2)
对我来说,这似乎更像是一个架构问题:
Nameable
作为协议很奇怪。从逻辑上讲,每个Animal都有能力被命名,因此Animal
应始终符合Nameable
如果没有命名动物而不是拥有可以拥有名称和动物的动物,那么允许nil
名称会更加简单。
然后,您只需Zoo
即可在assert
中强制执行名称。
答案 2 :(得分:1)
<>
在Objective-C中:符合协议
<>
在Swift中用于泛型
您可以使用where
关键字
在类型名称后面使用 where 来指定需求列表 - 例如,要求类型实现协议,要求两种类型相同,或者要求类有一个特定的超类。
摘自:Apple Inc.“The Swift Programming Language。”iBooks。
答案 3 :(得分:1)
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