假设我有:

protocol MyError: Error, Equatable {
  var errorDispalyTitle: String { get }
  var errorDisplayMessage: String { get }
}

enum ContentState {
  case .loading
  case .error(any MyError)
  case .contentLoaded
}

如果我在ContentState中实现Equatable以便我可以在单元测试期间进行比较,我最终会遇到一个问题,因为我必须比较两个any MyError类型,这两个类型是盒装的,可能属于两个不同的底层类型.

extension ContentState: Equatable {
  static func == (lhs: ContentState, rhs: ContentState) -> Bool {
    switch (lhs, rhs) {
    case (.loading, .loading):
      return true
    case (.contentLoaded, .contentLoaded):
      return true
    case (.error(let lhsError), .error(let rhsError)):
      // TODO: have to compare if both underlying types are match and then if they are equal in value
    default:
      return false
    }
  }
}

我该怎么做呢?

我try 将泛型从存在类型提升到类型(例如ContentState<Error: MyError>),这允许它在实现Equatable时编译,因为它知道如何推断类型,但问题是对于哪个类使用该枚举,接收它的类型并不重要,只有它是它的任何类型,如果我不实现any存在类型,它就会开始要求泛型沿着链向上传播.

推荐答案

从SWIFT 5.7、Swift automatically “opens” an existential when you pass it as an argument of generic type.开始,可以打开隐式self参数(事实上,SWIFT一直打开self参数),并且SWIFT可以在一次调用中打开多个参数.因此,我们可以编写一个isEqual(to:)函数,将任何Equatable与任何其他Equatable进行比较,如下所示:


extension Equatable {
    func isEqual<B: Equatable>(to b: B) -> Bool {
        return b as? Self == self
    }
}

然后我们可以像这样完成您的ContentState符合性:

extension ContentState: Equatable {
  static func == (lhs: ContentState, rhs: ContentState) -> Bool {
    switch (lhs, rhs) {
    case (.loading, .loading):
      return true
    case (.contentLoaded, .contentLoaded):
      return true
    case (.error(let lhsError), .error(let rhsError)):
        return lhsError.isEqual(to: rhsError)
    default:
      return false
    }
  }
}

Ios相关问答推荐

如何在进行滑动删除操作时保持自定义视图背景静态

Swift addtarget方法的默认参数不生效

如何访问iOS模拟器中的zoom 设置?(在搜索中列出,但不可见)

AVFoundation Camera推出变焦SWIFT

为什么AVSpeechSynthesizer复制的信息比我的文本多?

如何在后台显示 Swift UI 中的通讯通知?

UIView 阴影不适用于自定义扩展

拔下设备后,DriverKit USB 驱动程序 (dext) 进程不会终止

.frame() 修饰符的位置如何影响视图?

React Native IOS base64 编码图像不显示

iOS SwiftUI - 使用 PhotosPicker 从图库中 Select 图像或视频

Flutter iOS 构建失败并在 ios/Runner/AppDelegate.swift 中出现多个错误

Xcode 不支持 iOS 15.6

无法结合 UIImageView 旋转动画和 tableView 部分重新加载

禁用 UITextField 的自动更正

如何在 UIActivityViewController 中设置邮件主题?

在 iOS 7 上更改标签栏色调 colored颜色

SLComposeViewController 分享教程

iOS在应用程序中下载并保存图像

使用 swift 3 在 UIView 上添加阴影