web-dev-qa-db-ja.com

メソッドパラメータにタイプとプロトコルが必要

私は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[] = [];
}

パラメータとして渡されるオブジェクトがtypeaddAnimalprotocolに準拠Animalの両方である必要があるNamableメソッドをどのように記述しますか?そして、animals配列に対してどのように宣言しますか?

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

Objective-Cでは、次のように書きます

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

複数の条件を持つwhere句を含むジェネリックを使用できます。

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

修正:配列を正しく入力できるように、おそらくクラス全体をこのジェネリックにする必要があります

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

私には、これはアーキテクチャの問題のように思えます。

Nameableはプロトコルとしては奇妙です。論理的には、すべての動物には名前を付けることができるため、Animalは常にNameableに準拠する必要があります

名前を付けることができる動物と名前を付けることができない動物を使用する代わりに、動物に名前が付けられていない場合にnilの名前を許可する方がはるかに簡単です。

次に、Zooだけでassertの名前を強制できます。

2
Sulthan

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 
1
Philipp Otto

<>はObjective-Cにあります:プロトコルに準拠しています

<>はSwiftジェネリック医薬品の場合)

whereキーワードでさらに多くのことができます

タイプ名の後にwhereを使用して、要件のリストを指定します。たとえば、プロトコルを実装するためにタイプを要求する場合、2つのタイプを要求する場合などです。同じ、または特定のスーパークラスを持つクラスを要求する。

抜粋:Apple Inc.“ The Swift Programming Language。” iBooks

1
Binarian