如何使具有泛型属性的结构符合可等式?
Posted
技术标签:
【中文标题】如何使具有泛型属性的结构符合可等式?【英文标题】:How do I conform a struct with a generic property to equatable? 【发布时间】:2021-06-28 15:31:13 【问题描述】:我有以下结构:
struct IndexAndItem<ItemType>
let index: Int
let item: ItemType
我需要使IndexAndItem<MyClass>
符合Equatable
。
MyClass
已经符合Equatable
但是当我尝试时:
extension IndexAndItem: Equatable where ItemType == MyClass
internal static func == (lhs: IndexAndItem, rhs: IndexAndItem) -> Bool
lhs.item == rhs.item
我收到一个错误:
方法“==”必须声明为公共,因为它符合公共协议“Equatable”中的要求
将其更改为public
然后会引发另一个错误,要求将public
替换为internal
。
我在这里做错了什么?
【问题讨论】:
Xcode 12.5。不允许我标记为内部 为什么不简单地struct IndexAndItem<ItemType : Equatable> : Equatable ...
不带扩展名?
@vadian 我正在使用扩展,所以一致性只发生在测试目标中
@Kex 你做得不对,你不应该仅仅为了测试目的而增加你的应用程序代码。它可能感觉不那么嘈杂,但您实际上是在向那些偶然发现该单元测试代码的人引入错误的期望,期望生产结构是平等的。请改用辅助方法,或者如果有意义,请将 Equatable
一致性添加到应用代码中。
【参考方案1】:
正如上面 @vadian 建议的那样,您可以这样做 -
struct IndexAndItem<ItemType: Equatable>: Equatable
let index: Int
let itemType: ItemType
这样,您不必担心以后有更多 ItemType
类型与 IndexAndItem
一起使用。
如果您只是想知道如何让它以您尝试的方式工作,以下是我对两种 internal
类型的工作方式。
class MyClass: Equatable
let flag: Bool
init(flag: Bool) self.flag = flag
static func == (lhs: MyClass, rhs: MyClass) -> Bool
lhs.flag == rhs.flag
struct IndexAndItem<ItemType>
let index: Int
let itemType: ItemType
// Restricted to one type `MyClass`
extension IndexAndItem: Equatable where ItemType == MyClass
// Open to all types that conform to `Equatable`
extension IndexAndItem: Equatable where ItemType: Equatable
只要您的ItemType
符合Equatable
,编译器就可以为您综合符合性。您不需要实现任何方法。
【讨论】:
Restricted to one type
MyClass`。你如何定义static func == (lhs: IndexAndItem, rhs: IndexAndItem) -> Bool
?当我使用return lhs.item = rhs.item
时,我得到Cannot assign to property: 'item' is a 'let' constant
这种情况下不需要定义static func ==
,编译器可以自动合成它的实现。这就是答案的最后一行所说的。以上是关于如何使具有泛型属性的结构符合可等式?的主要内容,如果未能解决你的问题,请参考以下文章