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

Swift中枚举遵循Equatable协议:未遵循Hashable时如何实现相等判断方法

Swift枚举遵循Equatable协议的疑问:hashValue访问权限与手动实现相等判断

问题描述

我写了一段让枚举显式遵循Equatable协议的代码:

enum TestEnum: Equatable {
    case one, two, three, four, five
    static func ==(lhs: TestEnum, rhs: TestEnum) -> Bool {
        return lhs.hashValue == rhs.hashValue
    }
}

这里我用hashValue来做相等判断,但我有个疑问:我并没有让这个枚举遵循Hashable协议,为什么可以直接访问hashValue?

我的核心问题是:如果我的枚举只遵循Equatable、不遵循Hashable,而且无法访问hashValue的情况下,该怎么手动实现==方法来判断两个枚举值是否相等?


解答

1. 为什么没显式遵循Hashable却能访问hashValue?

在Swift中,没有关联值的枚举会被编译器自动赋予Equatable和Hashable的合成实现——哪怕你只显式声明了Equatable,编译器也会隐式地让它同时遵循Hashable协议。这是因为对于这类简单枚举,每个case都是唯一且可哈希的,编译器可以自动完成所有必要的实现,包括生成hashValue(在Swift 5.1及以后版本中是hash(into:)方法)。

所以你的TestEnum虽然只写了: Equatable,但实际上已经隐式遵循了Hashable,自然就能访问hashValue了。

2. 仅遵循Equatable时,如何手动实现==方法?

首先要明确:对于无关联值的枚举,你完全不需要手动实现==方法——编译器会自动为你合成正确的相等判断逻辑,直接写下面的代码就足够了:

enum TestEnum: Equatable {
    case one, two, three, four, five
}

如果出于学习或特殊需求一定要手动实现,有两种直观的方式:

方式一:通过switch匹配枚举case组合

enum TestEnum: Equatable {
    case one, two, three, four, five
    static func ==(lhs: TestEnum, rhs: TestEnum) -> Bool {
        switch (lhs, rhs) {
        case (.one, .one), (.two, .two), (.three, .three), (.four, .four), (.five, .five):
            return true
        default:
            return false
        }
    }
}

方式二:针对单个枚举case逐一判断

enum TestEnum: Equatable {
    case one, two, three, four, five
    static func ==(lhs: TestEnum, rhs: TestEnum) -> Bool {
        switch lhs {
        case .one: return rhs == .one
        case .two: return rhs == .two
        case .three: return rhs == .three
        case .four: return rhs == .four
        case .five: return rhs == .five
        }
    }
}

如果你的枚举带有关联值,手动实现==时需要同时匹配case和关联值(关联值需遵循Equatable才能直接比较):

enum TestEnum: Equatable {
    case number(Int)
    case text(String)
    
    static func ==(lhs: TestEnum, rhs: TestEnum) -> Bool {
        switch (lhs, rhs) {
        case let (.number(left), .number(right)) where left == right:
            return true
        case let (.text(left), .text(right)) where left == right:
            return true
        default:
            return false
        }
    }
}

内容的提问来源于stack exchange,提问作者user17958761

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 13:03:10