Rah*_*iya 3 generics ios swift swift-protocols
很长一段时间以来,我一直在努力使用Swift协议和关联类型.我再次使用基本功能来真正理解出现了什么问题,我在Rob Napier的Swift Protocols中使用了相关类型要求的TypeErasure 文章,但我仍然没有运气.
找到下面的代码
// 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())
}
Run Code Online (Sandbox Code Playgroud)
现在我想在协议Animal中给出一个默认实现,如下所示
extension Animal {
func feed(food: Food) -> Void {
print("unknown")
}
}
Run Code Online (Sandbox Code Playgroud)
当我从struct Cow中删除该函数时,我得到了Cow不符合Protocol Animal的错误消息.
这是否意味着你不能同时使用Type Erasures和Default Implementation?有什么方法我可以做TypeErasure并保持默认实现?
该问题与类型擦除无关,如果删除struct AnyAnimal<Food>定义,您将收到相同的错误消息.
如果feed()从中删除该方法,struct Cow则编译器无法推断关联的类型Food.所以要么在默认实现中使用具体类型:
extension Animal {
func feed(food: Grass) -> Void {
print("unknown")
}
}
struct Cow: Animal {
}
Run Code Online (Sandbox Code Playgroud)
或者Food使用默认实现为每种类型定义类型别名:
extension Animal {
func feed(food: Food) -> Void {
print("unknown")
}
}
struct Cow: Animal {
typealias Food = Grass
}
Run Code Online (Sandbox Code Playgroud)
也可以Food在协议中定义默认类型:
protocol Animal {
associatedtype Food = Grass
func feed(food: Food) -> Void
}
extension Animal {
func feed(food: Food) -> Void {
print("unknown")
}
}
struct Cow: Animal {
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1593 次 |
| 最近记录: |