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

创建返回Roll结构体的RawRepresentable枚举失败,遇类型匹配错误

解决枚举RawRepresentable使用结构体作为RawValue的错误

你遇到的这个错误,核心原因是Swift无法直接将结构体实例作为switch的表达式模式进行匹配——你的Roll结构体默认没有实现Equatable协议,编译器不知道该如何比较两个Roll实例是否相等;而且就算实现了Equatable,直接用新创建的实例去匹配rawValue也不是最优写法。

快速修复方案:直接比较结构体的属性

既然你的枚举和Roll的映射关系完全基于times字符串,那我们可以在init?(rawValue:)里直接判断rawValue的times属性,而不是创建新的Roll实例来匹配。修改后的代码如下:

import Foundation
struct Roll {
    let times: String
    init(with times: String) {
        self.times = times
    }
}

fileprivate enum Requests {
    case poker
    case cards
    case slots
}

extension Requests: RawRepresentable {
    typealias RawValue = Roll
    
    init?(rawValue: RawValue) {
        // 改为比较rawValue的times属性
        switch rawValue.times {
        case "once":
            self = .poker
        case "twice":
            self = .cards
        case "a couple of times":
            self = .slots
        default:
            return nil
        }
    }
    
    var rawValue: RawValue {
        switch self {
        case .poker:
            return Roll(with: "once")
        case .cards:
            return Roll(with: "twice")
        case .slots:
            return Roll(with: "a couple of times")
        }
    }
}

这样修改后,Requests.cards.rawValue就能正常返回Roll(times: "twice"),反向的Requests(rawValue: Roll(with: "twice"))也能正确解析为.cards。

备选方案:让结构体实现Equatable

如果你确实需要让Roll支持实例间的相等比较(比如其他业务场景需要),可以让Roll实现Equatable协议,这样原来的switch写法也能生效:

// 给Roll添加Equatable实现
struct Roll: Equatable {
    let times: String
    init(with times: String) {
        self.times = times
    }
    
    // Swift 5.5+可以自动合成Equatable实现,这里也可以手动写
    static func == (lhs: Roll, rhs: Roll) -> Bool {
        return lhs.times == rhs.times
    }
}

不过第一种方案更直接高效,因为我们本来就只关心times字符串的值,没必要额外创建新的Roll实例来做比较。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:12:56