2016-04-23 6 views
2

私は長い間Swiftプロトコルと関連タイプで非常に苦労してきました。私は何がうまくいかないのかを実際に理解するために基本的なことをやり直しました。そして、これをRobot NapierのSwift ProtocolsでTypeErasureのarticleに従いましたが、まだ運がありません。関連付けられたタイプの要件とデフォルトの実装を備えたスウィフトプロトコル

// An Animal can eat 
protocol Animal { 
    associatedtype Food 
    func feed(food: Food) -> Void 
} 

struct AnyAnimal<Food>: Animal { 
    private let _feed: (Food) -> Void 
    init<Base: Animal where Food == Base.Food>(_ base: Base) { 
     _feed = base.feed 
    } 
    func feed(food: Food) { _feed(food) } 
} 

// Kinds of Food 
struct Grass {} 

struct Cow: Animal { 
    func feed(food: Grass) { print("moo") } 
} 

struct Goat: Animal { 
    func feed(food: Grass) { print("bah") } 
} 

let grassEaters = [AnyAnimal(Cow()), AnyAnimal(Goat())] 
for animal in grassEaters { 
    animal.feed(Grass()) 
} 

以下のコードを探すには、今、私は以下の

extension Animal { 

    func feed(food: Food) -> Void { 
     print("unknown") 
    } 
} 

のようなプロトコルの動物でのデフォルトの実装を与えたかったと私は、構造体の牛から機能を削除したとき、私はエラーを取得しますCowがProtocol Animalに準拠していないというメッセージ。

これは、タイプ消去とデフォルト実装を一緒に使用できないことを意味しますか。 TypeErasureを実行してデフォルト実装を維持する方法はありますか?

答えて

5

struct AnyAnimal<Food>定義を削除すると、問題はタイプ消去とは無関係で、同じ エラーメッセージが表示されます。

コンパイラは、関連するタイプFoodを推測することはできません ますが、その後struct Cowからfeed()方法を削除した場合。だから、どちらかのデフォルトの実装では、具体的な型を使用 :

extension Animal { 
    func feed(food: Grass) -> Void { 
     print("unknown") 
    } 
} 

struct Cow: Animal { 
} 

か、 デフォルトの実装を使用して、各タイプのタイプの別名Foodを定義します。

extension Animal { 
    func feed(food: Food) -> Void { 
     print("unknown") 
    } 
} 

struct Cow: Animal { 
    typealias Food = Grass 
} 

定義することも可能です プロトコルでFoodのデフォルトのタイプ:

protocol Animal { 
    associatedtype Food = Grass 
    func feed(food: Food) -> Void 
} 


extension Animal { 
    func feed(food: Food) -> Void { 
     print("unknown") 
    } 
} 

struct Cow: Animal { 
} 
+0

私の悪い、私は実現しませんでしたそれはとてもばかげた質問だった。ありがとうございました! –

関連する問題