私は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[] = [];
}
パラメータとして渡されるオブジェクトがtypeaddAnimal
とprotocolに準拠Animal
の両方である必要があるNamable
メソッドをどのように記述しますか?そして、animals
配列に対してどのように宣言しますか?
func addAnimal:(animal: ????) { ... }
Objective-Cでは、次のように書きます
- (void)addAnimal:(Animal<Namable>*)animal {...}
複数の条件を持つwhere
句を含むジェネリックを使用できます。
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
に準拠する必要があります
名前を付けることができる動物と名前を付けることができない動物を使用する代わりに、動物に名前が付けられていない場合にnil
の名前を許可する方がはるかに簡単です。
次に、Zoo
だけでassert
の名前を強制できます。
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
<>
はObjective-Cにあります:プロトコルに準拠しています
<>
はSwiftジェネリック医薬品の場合)
where
キーワードでさらに多くのことができます
タイプ名の後にwhereを使用して、要件のリストを指定します。たとえば、プロトコルを実装するためにタイプを要求する場合、2つのタイプを要求する場合などです。同じ、または特定のスーパークラスを持つクラスを要求する。
抜粋:Apple Inc.“ The Swift Programming Language。” iBooks 。