Considere esta enumeración:
enum DataType { case One (data: Int) case Two (value: String) }Swift tiene coincidencia de patrones para comparar una enumeración con valores asociados, así:
let var1 = DataType.One(data: 123) let var2 = DataType.One(data: 456) if case DataType.One(data: _) = var2 { print ("var2 is DataType.One") }¿Cómo se compararía no una variable con un tipo de enumeración, sino comparando el tipo de enumeración de dos variables? Vi un montón de preguntas similares, pero ninguna se centró en el caso en el que tienes dos variables.
Básicamente lo que quiero es:
if case var1 = var2 { print ("var1 is the same enum type as var2") }Enfoque actualizado:
Creo que no hay soporte nativo para esto. Pero puede lograrlo definiendo un operador personalizado (preferiblemente usando un protocolo, pero también puede hacerlo directamente). Algo como esto:
protocol EnumTypeEquatable { static func ~=(lhs: Self, rhs: Self) -> Bool } extension DataType: EnumTypeEquatable { static func ~=(lhs: DataType, rhs: DataType) -> Bool { switch (lhs, rhs) { case (.one, .one), (.two, .two): return true default: return false } } }Y luego úsalo como:
let isTypeEqual = DataType.One(value: 1) ~= DataType.One(value: 2) print (isTypeEqual) // true
Viejo enfoque:
protocol EnumTypeEquatable { var enumCaseIdentifier: String { get } } extension DataType: EnumTypeEquatable { var enumCaseIdentifier: String { switch self { case .one: return "ONE" case .two: return "TWO" } } } func ~=<T>(lhs: T, rhs: T) -> Bool where T: EnumTypeEquatable { return lhs.enumCaseIdentifier == rhs.enumCaseIdentifier } La versión anterior depende de Runtime y se puede proporcionar con la implementación predeterminada de enumCaseIdentifier según String(describing: self) que no se recomienda. (ya que String(describing: self) está trabajando con el protocolo CustromStringConvertible y puede modificarse)
Simplemente confirme a Equatable como a continuación
extension DataType: Equatable { static func == (lhs: DataType, rhs: DataType) -> Bool { switch (lhs, rhs) { case (.One, .Two), (.Two, .One): return false case (.One, .One), (.Two, .Two): return true } } } Si no desea implementar Equatable , simplemente mueva el contenido al método de instancia:
extension DataType{ func isSame(_ other: DataType) -> Bool { switch (self, other) { case (.One, .Two), (.Two, .One): return false case (.One, .One), (.Two, .Two): return true } } }Usar:
let isTypeEqual = DataType.One(value: 1).isSame(DataType.One(value: 2)) print (isTypeEqual) // trueEsto funcionó para mí:
enum DataType { case one (data: Int) case two (value: String) } protocol EnumTypeEquatable { static func sameType(lhs: Self, rhs: Self) -> Bool } extension DataType: EnumTypeEquatable { static func sameType(lhs: DataType, rhs: DataType) -> Bool { if let caseLhs = Mirror(reflecting: lhs).children.first?.label, let caseRhs = Mirror(reflecting: rhs).children.first?.label { return (caseLhs == caseRhs) } else { return false } } } let isTypeEqual = DataType.sameType(lhs: .one(data: 1), rhs: .one(data: 2)) print (isTypeEqual) // true