swift – 自定义模式匹配失败,“Enum case不是type的成员”

我正在尝试编写一个自定义模式匹配,让我打开错误并匹配错误代码.请参阅以下示例:

enum ErrorCode: Int {
  case notSoDumb
  case dumbError
}

let myError = NSError(domain: "My domain",code: ErrorCode.dumbError.rawValue,userInfo: nil)

func ~=(pattern: ErrorCode,value: NSError) -> Bool {
  return (ErrorCode(rawValue: value.code) == pattern)
}

switch myError {
case ErrorCode.notSoDumb:
  print("Not a dumb error")
case ErrorCode.dumbError:
  print("Super dumb error")
default:
  print("No matches!")
}

我的switch语句中的第一个案例有一个Enum案例错误’notSoDumb’不是’NSError’类型的成员.如果我用整数替换ErrorCode枚举(并更新我的自定义〜=运算符以匹配Ints和NSErrors,一切正常.

解决方法

这是 a known bug与模式匹配的枚举案例;编译器错误地认为它始终使用 enumeration case pattern而不是 expression pattern.

在修复之前,强制编译器进入“表达式模式”的一种方法是首先绑定一个临时的case:

let notSoDumbErrorCode = ErrorCode.notSoDumb
let dumbErrorCode = ErrorCode.dumbError

switch myError {
case notSoDumbErrorCode:
  print("Not a dumb error")
case dumbErrorCode:
  print("Super dumb error")
default:
  print("No matches!")
}

然而,这非常笨重.一个更好的解决方法是使用带静态成员而不是枚举的结构:

import Foundation

struct ErrorCode : Equatable,RawRepresentable {

  let rawValue: Int

  static let notSoDumb = ErrorCode(rawValue: 0)
  static let dumbError = ErrorCode(rawValue: 1)
}

let myError = NSError(domain: "My domain",value: NSError) -> Bool {
  return value.code == pattern.rawValue
}

switch myError {
case ErrorCode.notSoDumb:
  print("Not a dumb error")
case ErrorCode.dumbError:
  print("Super dumb error")
default:
  print("No matches!")
}

这也使您可以在以后通过扩展添加其他错误代码(它的行为更像是一个打开的枚举).虽然它确实从init(rawValue :)中删除了验证,这可能是也可能不是(你可以总是实现自己的init?(rawValue :)).

或者,as you say in your comment,您可以坚持使用枚举,但在模式匹配时使用中间函数调用以强制编译器进入“表达式模式”:

enum ErrorCode : Int {
  case notSoDumb
  case dumbError
}

// ...

func identity<T>(_ t: T) -> T { return t }

switch myError {
case identity(ErrorCode.notSoDumb):
  print("Not a dumb error")
case identity(ErrorCode.dumbError):
  print("Super dumb error")
default:
  print("No matches!")
}

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...