Swift 具有关联类型要求和默认实现的协议
Swift Protocols with Associated Type Requirement and Default Implementation
长期以来,我一直在努力研究 Swift 协议和关联类型。我再次从基础开始,真正理解出了什么问题,我遵循了 Rob Napier 在 Swift 具有关联类型要求的协议中的 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())
}
现在我想在协议 Animal 中提供一个默认实现,如下所示
extension Animal {
func feed(food: Food) -> Void {
print("unknown")
}
}
当我从 struct Cow 中删除函数时,我收到 Cow 不符合 Protocol Animal 的错误消息。
这是否意味着您不能同时使用类型擦除和默认实现?。有什么方法可以让我执行 TypeErasure 并保留默认实现吗?
问题与类型擦除无关,你会得到同样的结果
如果删除 struct AnyAnimal<Food>
定义,则会出现错误消息。
如果从 struct Cow
中删除 feed()
方法,则
编译器无法推断关联类型 Food
。所以要么你
在默认实现中使用具体类型:
extension Animal {
func feed(food: Grass) -> Void {
print("unknown")
}
}
struct Cow: Animal {
}
或者您使用
默认实现:
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 {
}
长期以来,我一直在努力研究 Swift 协议和关联类型。我再次从基础开始,真正理解出了什么问题,我遵循了 Rob Napier 在 Swift 具有关联类型要求的协议中的 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())
}
现在我想在协议 Animal 中提供一个默认实现,如下所示
extension Animal {
func feed(food: Food) -> Void {
print("unknown")
}
}
当我从 struct Cow 中删除函数时,我收到 Cow 不符合 Protocol Animal 的错误消息。
这是否意味着您不能同时使用类型擦除和默认实现?。有什么方法可以让我执行 TypeErasure 并保留默认实现吗?
问题与类型擦除无关,你会得到同样的结果
如果删除 struct AnyAnimal<Food>
定义,则会出现错误消息。
如果从 struct Cow
中删除 feed()
方法,则
编译器无法推断关联类型 Food
。所以要么你
在默认实现中使用具体类型:
extension Animal {
func feed(food: Grass) -> Void {
print("unknown")
}
}
struct Cow: Animal {
}
或者您使用 默认实现:
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 {
}