Require type and protocol for method parameter

亡梦爱人 提交于 2020-01-10 08:41:40

问题


I am playing around with Swift and am stumbling over the following problem: given I have the predefined class Animal:

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

I now write the class Zoo with the constructor accepting animals. But the Zoo wants every animal to have a name and hence defines the Namable protocol.

protocol Namable {
    var name: String {get}
}

class Zoo {
    var animals: Animal[] = [];
}

How would you write an addAnimal method that requires the object being passed as parameter to be both of type Animal and conform to protocol Namable? And how do you declare that for the animals array?

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

In Objective-C, I'd write something like this

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

回答1:


You can use a generic with a where clause with multiple conditions.

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

Amendment: You should probably make the whole class this generic so you can type the array properly

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



回答2:


To me, this seems more an architecture problem:

Nameable is strange as a protocol. Logically, every Animal has the ability to be named so Animal should always conform to Nameable

It would be much simpler to allow for nil names when the animal is not named instead of having animals that can have a name and animals that can't.

Then you can enforce names in Zoo simply by an assert.




回答3:


<> is in Objective-C: conforms to protocol

<> is in Swift for generics

You can do more with the where keyword

Use where after the type name to specify a list of requirements—for example, to require the type to implement a protocol, to require two types to be the same, or to require a class to have a particular superclass.

Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks.




回答4:


Swift 3 version

In Swift 3 the structure changed a bit. That´s why you will get a deprecation warning for the old structure. Here´s the new one:

For functions the expected protocols are located after the parameters definition of the function. Example:

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

For enums or classes the structure also changed

enum ZooEnum<T: Animal> where T: Nameable 

class Zoo<T: Animal> where T: Nameable 


来源:https://stackoverflow.com/questions/24231498/require-type-and-protocol-for-method-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!