You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 06:43:15