![](/img/trans.png)
[英]How to compare enum with associated values by ignoring its associated value in Swift?
[英]Compare Swift Enum types ignoring associated values - generic implementation
我的项目中有几个不同的枚举,符合相同的协议。 协议中的compareEnumType
方法比较忽略关联值的枚举情况。 这是我在游乐场的代码:
protocol EquatableEnumType {
static func compareEnumType(lhs: Self, rhs: Self) -> Bool
}
enum MyEnum: EquatableEnumType {
case A(Int)
case B
static func compareEnumType(lhs: MyEnum, rhs: MyEnum) -> Bool {
switch (lhs, rhs) {
case (.A, .A): return true
case (.B, .B): return true
default: return false
}
}
}
enum MyEnum2: EquatableEnumType {
case X(String)
case Y
static func compareEnumType(lhs: MyEnum2, rhs: MyEnum2) -> Bool {
switch (lhs, rhs) {
case (.X, .X): return true
case (.Y, .Y): return true
default: return false
}
}
}
let a = MyEnum.A(5)
let a1 = MyEnum.A(3)
if MyEnum.compareEnumType(lhs: a, rhs: a1) {
print("equal") // -> true, prints "equal"
}
let x = MyEnum2.X("table")
let x1 = MyEnum2.X("chair")
if MyEnum2.compareEnumType(lhs: x, rhs: x1) {
print("equal2") // -> true, prints "equal2"
}
在我的真实项目中,我有两个以上的枚举,对于每个枚举,我必须有compareEnumType
函数的类似实现。
问题是:是否可以使用compareEnumType
的通用实现,它适用于符合EquatableEnumType
协议的所有枚举?
我尝试在协议扩展中编写一个默认实现,如下所示:
extension EquatableEnumType {
static func compareEnumType(lhs: Self, rhs: Self) -> Bool {
// how to implement???
}
}
但我坚持实施。 我没有看到访问lhs
和rhs
包含的值的方法。 谁能帮助我?
我不认为你可以自动生成这个,所以这是一种使用扩展的方式。 我建议创建一个新的enum CompareEnumMethod
,它告诉您是要比较关联的values
还是仅比较type
。 在您的协议中创建一个新函数compareEnum
,该函数将此枚举作为参数。 然后,您可以为==(lhs:,rhs:)
创建一个扩展名,并说它使用.value
而对于compareEnumType
,则使用.type
。 现在只需要在每个枚举中实现compareEnum
方法。
enum CompareEnumMethod {
case type, value
}
protocol EquatableEnumType: Equatable {
static func compareEnumType(lhs: Self, rhs: Self) -> Bool
static func compareEnum(lhs: Self, rhs: Self, method: CompareEnumMethod) -> Bool
}
extension EquatableEnumType {
static func compareEnumType(lhs: Self, rhs: Self) -> Bool {
return Self.compareEnum(lhs: lhs, rhs: rhs, method: .type)
}
static func ==(lhs: Self, rhs: Self) -> Bool {
return Self.compareEnum(lhs: lhs, rhs: rhs, method: .value)
}
}
enum MyEnum: EquatableEnumType {
case A(Int)
case B
static func compareEnum(lhs: MyEnum, rhs: MyEnum, method: CompareEnumMethod) -> Bool {
switch (lhs, rhs, method) {
case let (.A(lhsA), .A(rhsA), .value):
return lhsA == rhsA
case (.A, .A, .type),
(.B, .B, _):
return true
default:
return false
}
}
}
let a0 = MyEnum.A(5)
let a1 = MyEnum.A(3)
let b0 = MyEnum.B
print(MyEnum.compareEnumType(lhs: a0, rhs: a1)) //true
print(a0 == a1) //false
print(MyEnum.compareEnumType(lhs: a0, rhs: b0)) //false
简单! 我会使用一个实例方法,但你可以将它重写为类函数,如果你真的需要它是静态的。
extension EquatableEnumCase {
func isSameCase(as other: Self) -> Bool {
let mirrorSelf = Mirror(reflecting: self)
let mirrorOther = Mirror(reflecting: other)
if let caseSelf = mirrorSelf.children.first?.label, let caseOther = mirrorOther.children.first?.label {
return (caseSelf == caseOther) //Avoid nil comparation, because (nil == nil) returns true
} else { return false}
}
}
enum MyEnum1: EquatableEnumCase {
case A(Int)
case B
}
enum MyEnum2: EquatableEnumCase {
case X(String)
case Y
}
let a = MyEnum1.A(5)
let a1 = MyEnum1.A(3)
if a.isSameCase(as: a1) {
print("equal") // -> true, prints "equal1"
}
let x = MyEnum2.X("table")
let x1 = MyEnum2.X("chair")
if x.isSameCase(as: x1) {
print("equal2") // -> true, prints "equal2"
}
let y = MyEnum2.Y
print(x.isSameCase(as: y) ? "equal3": "not equal3") // -> false, "not equal3"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.