带关联值的Swift枚举相等性实现及类型检测报错求助
解决带关联值枚举的相等性判断与类型识别问题
嘿,我来帮你搞定这个问题!你的代码有两个核心问题:一是SlideTemplate的Equatable协议实现不完整,二是判断模板类型的方式用错了。咱们一步步来解决:
1. 先让SlideContent遵循Equatable
因为SlideTemplate的关联值是SlideContent,要实现SlideTemplate的相等性,首先得让SlideContent也遵循Equatable。注意UIImage默认不支持Equatable,所以我们需要自定义图片的比较逻辑(比如通过图片的二进制数据来判断):
enum SlideContent: Equatable { case text(content: String) case image(content: UIImage) static func == (lhs: SlideContent, rhs: SlideContent) -> Bool { switch (lhs, rhs) { case (.text(let lhsText), .text(let rhsText)): return lhsText == rhsText case (.image(let lhsImage), .image(let rhsImage)): // 用PNG数据比较图片,也可以换成JPEG数据,根据需求调整 guard let lhsData = lhsImage.pngData(), let rhsData = rhsImage.pngData() else { return false } return lhsData == rhsData default: return false } } }
2. 正确实现SlideTemplate的Equatable协议
现在可以完整实现SlideTemplate的相等性判断,逐个case匹配并比较关联值:
enum SlideTemplate: Equatable { case centered(content: SlideContent) case horizontalSplit(leftContent: SlideContent, rightContent: SlideContent) case empty static func == (lhs: SlideTemplate, rhs: SlideTemplate) -> Bool { switch (lhs, rhs) { case (.centered(let lhsContent), .centered(let rhsContent)): return lhsContent == rhsContent case (.horizontalSplit(let lhsLeft, let lhsRight), .horizontalSplit(let rhsLeft, let rhsRight)): return lhsLeft == rhsLeft && lhsRight == rhsRight case (.empty, .empty): return true default: return false } } }
3. 修改模板类型判断函数
你之前的报错核心原因是:SlideTemplate.centered是一个构造器函数(接受SlideContent返回SlideTemplate实例),不是枚举实例,所以不能直接用==和slide.template(枚举实例)比较。
正确的做法是用switch语句做模式匹配,这也是Swift处理带关联值枚举的标准方式:
func getSlideTemplate(slide: Slide) { switch slide.template { case .centered: print("centered") case .horizontalSplit: print("horizontalSplit") case .empty: print("empty") } }
如果需要同时获取关联值,也可以在case里直接提取:
func getSlideTemplateWithContent(slide: Slide) { switch slide.template { case .centered(let content): print("centered, content: \(content)") case .horizontalSplit(let left, let right): print("horizontalSplit, left: \(left), right: \(right)") case .empty: print("empty") } }
完整测试代码
最后把结构体和测试代码整合起来,就能正常运行了:
import UIKit enum SlideContent: Equatable { case text(content: String) case image(content: UIImage) static func == (lhs: SlideContent, rhs: SlideContent) -> Bool { switch (lhs, rhs) { case (.text(let lhsText), .text(let rhsText)): return lhsText == rhsText case (.image(let lhsImage), .image(let rhsImage)): guard let lhsData = lhsImage.pngData(), let rhsData = rhsImage.pngData() else { return false } return lhsData == rhsData default: return false } } } enum SlideTemplate: Equatable { case centered(content: SlideContent) case horizontalSplit(leftContent: SlideContent, rightContent: SlideContent) case empty static func == (lhs: SlideTemplate, rhs: SlideTemplate) -> Bool { switch (lhs, rhs) { case (.centered(let lhsContent), .centered(let rhsContent)): return lhsContent == rhsContent case (.horizontalSplit(let lhsLeft, let lhsRight), .horizontalSplit(let rhsLeft, let rhsRight)): return lhsLeft == rhsLeft && lhsRight == rhsRight case (.empty, .empty): return true default: return false } } } struct Slide { let template: SlideTemplate } func getSlideTemplate(slide: Slide) { switch slide.template { case .centered: print("centered") case .horizontalSplit: print("horizontalSplit") case .empty: print("empty") } } // 测试 let textContent = SlideContent.text(content: "Hello") let centeredSlide = Slide(template: .centered(content: textContent)) getSlideTemplate(slide: centeredSlide) // 输出: centered let emptySlide = Slide(template: .empty) getSlideTemplate(slide: emptySlide) // 输出: empty
内容的提问来源于stack exchange,提问作者Human Cyborg Relations
相关产品推荐
相关产品推荐

