创建返回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
相关产品推荐
相关产品推荐

