Hashable结构体添加Delegate属性,能否无需手动实现Equatable/Hashable方法?
问题原因
你遇到的报错是因为添加的weak var delegate是可变的引用类型属性:
- Swift对
Hashable的自动合成要求实例的哈希值在生命周期内保持稳定,而可变属性可能导致哈希值变化,因此编译器无法自动生成符合要求的默认实现。 - 即使是不可变的引用类型属性,自动合成的
Equatable/Hashable也会把它纳入相等性和哈希计算,但你希望忽略这个属性。
解决方案
如果你不想手动编写static func ==和hash(into:)方法,可以通过Swift的私有属性标记让编译器忽略delegate,只基于其他属性自动合成协议实现:
protocol SomeDelegate: AnyObject { func delegateMethod() } struct Model: Hashable { let titleText: String @_nonEquatable @_nonHashable weak var delegate: SomeDelegate? }
@_nonEquatable和@_nonHashable会告诉编译器在合成Equatable和Hashable的默认实现时,跳过标记的属性,无需你手动编写任何协议方法。
替代方案(若不愿使用未公开API)
如果你不想依赖未公开属性,可以手动实现协议方法,代码量极小:
protocol SomeDelegate: AnyObject { func delegateMethod() } struct Model: Hashable { let titleText: String weak var delegate: SomeDelegate? static func == (lhs: Model, rhs: Model) -> Bool { lhs.titleText == rhs.titleText } func hash(into hasher: inout Hasher) { hasher.combine(titleText) } }
这种方式明确指定仅titleText参与相等性和哈希计算,完全符合你的需求。
内容的提问来源于stack exchange,提问作者NyanNyan
相关产品推荐
相关产品推荐

