具有关联types需求和默认实现的Swift协议

很长一段时间,我一直在使用Swift协议和相关types进行非常艰苦的努力。 我重新开始了基本的真正了解什么是错误的,我遵循这篇文章的types擦除在相关types的要求,由罗布纳皮尔的Swift协议,但我仍然没有运气。

find下面的代码

// 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") } } 

当我从结构牛中删除函数,我得到牛不符合协议动物的错误消息。

这是否意味着你不能一起使用types擦除和默认实现? 有什么办法可以做TypeErasure,并保持默认实现?

问题与types擦除无关,如果您删除struct AnyAnimal<Food>定义,您将得到相同的错误信息。

如果你从struct Cow移除feed()方法,那么编译器不能推断出相关的typesFood 。 所以要么在默认实现中使用具体types:

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

或者使用默认实现为每个types定义一个types别名Food

 extension Animal { func feed(food: Food) -> Void { print("unknown") } } struct Cow: Animal { typealias Food = Grass } 

也可以在协议中定义Food的默认types:

 protocol Animal { associatedtype Food = Grass func feed(food: Food) -> Void } extension Animal { func feed(food: Food) -> Void { print("unknown") } } struct Cow: Animal { }