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

编程入门 行业动态 更新时间:2024-10-25 06:32:26
本文介绍了具有关联类型需求和默认实现的Swift协议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 很长一段时间,我一直在用Swift协议和相关类型非常努力地努力。我重新开始了基本的工作,以真正了解发生了什么问题,并且我遵循这个有关关联类型的Swift协议中TypeErasure的文章罗布纳皮尔的要求,但我仍然没有运气。

找到下面的代码

//动物可以吃协议动物{相关类型食物 func feed(食物:食物) - > 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)} } //各种食物 struct Grass {} struct Cow:Animal { func feed(food:Grass){print(moo)} } struct Goat:Animal { func feed(food:Grass){print(bah) } } 让grassEaters = [AnyAnimal(Cow()),AnyAnimal(Goat())] for grassEaters { animal.feed(Grass ())}

现在我想在协议Animal中给出一个默认实现以下

扩展动物{ func feed(food:Food) - > Void { print(unknown)} }

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

这是否意味着您不能使用Type Erasures和默认实现在一起?有什么办法可以做TypeErasure并保持默认实现?

解决方案

问题与类型擦除无关,如果您删除 struct AnyAnimal< Food> 定义,则会得到相同的错误消息。

如果您从 struct Cow 然后中删除 feed()方法,编译器无法推断关联的类型食品。因此,无论您在默认实现中使用了一个具体类型:

extension动物{ func feed食物:草) - > Void { print(unknown)} } struct Cow:Animal {}

或者使用的默认实现为每个类型定义一个类型别名 Food :

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

也可以为 Food 在协议中:

协议动物{ associatedtype Food = Grass func feed (食物:食物) - >无效} 扩展动物{ func feed(food:Food) - > Void { print(unknown)} } struct Cow:Animal {}

I have been struggling very hard with Swift Protocols and Associated Types for a long time. I started again with basic to really understand what is going wrong and I followed this article of TypeErasure in Swift Protocols with Associated Type Requirement by Rob Napier but still i have no luck.

Find the code below

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

Now i wanted to give a default implementation in the protocol Animal like below

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

And when i removed the function from the struct Cow i get the error message that Cow doesn't conform to Protocol Animal.

Does that mean you cannot have Type Erasures and Default Implementation together?. Is there any way where i can do TypeErasure and also keep a Default Implementation?

解决方案

The problem is unrelated to the type erasure and you'll get the same error message if you remove the struct AnyAnimal<Food> definition.

If you remove the feed() method from struct Cow then the compiler cannot infer the associated type Food. So either you use a concrete type in the default implementation:

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

or you define a type alias Food for each type using the default implementation:

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

It is also possible to define a default type for Food in the protocol:

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

更多推荐

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

本文发布于:2023-10-28 08:35:57,感谢您对本站的认可!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:协议   需求   类型   Swift

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!