需要方法参数的类型和协议

时间:2014-06-15 16:05:15

标签: ios xcode cocoa protocols swift

我正在玩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 {...}

4 个答案:

答案 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