几天前,我问过这个问题。
绝妙的解决方案是这样的:
enum MyEnum {
case one
case two
case three(user: String)
func isOfSameType(_ other: MyEnum) -> Bool {
switch (self, other) {
case (.one, .one):
return true
case (.two, .two):
return true
case (.three, .three):
return true
default:
return false
}
}
}
var array: [MyEnum] = []
func add(_ value: MyEnum) {
if array.contains(where: { value.isOfSameType($0) }) { return }
array.append(value)
}
现在,用冷血分析,这似乎完全是黑魔法。
开关没有参数怎么比较东西?
但是现在我需要检查堆栈
上的最后一个元素是否属于三
。
像这样的东西
if array!.last.isOfType(.three) {
}
这将不起作用。Xcode将需要从.3开始的参数。
因为我不明白到目前为止我有什么,我不知道如何做到这一点。
您只需要使您的枚举符合Equable并比较关联的值是否相等:
enum MyEnum: Equatable {
case one
case two
case three(user: String)
}
var array: [MyEnum] = []
func add(_ value: MyEnum) {
if array.contains(value) { return }
array.append(value)
}
add(.one)
add(.one)
array
add(.three(user: "a"))
add(.three(user: "b"))
add(.three(user: "a"))
array[0] // one
array[1] // three(user: "a")
array[2] // three(user: "b")
检查最后一个元素是否为case.3:
if case .three = array.last {
print(true)
}
Swift枚举很特别,有很多别人没有的特性。然而,它是一个枚举,就像C样式的枚举和整数一样简单。枚举的实例只是一个值。
在你的例子中,
enum MyEnum {
case one
case two
case three(user: String)
}
假设你有一个数组,
let arrayMyEnum: [MyEnum] = [.one, .two, .three(user: "Mike"), .two, .three(user: "John")]
然后,你可以,
// basic approach
arrayMyEnum.contains {
switch $0 {
case .three(let user):
return true
default:
return false
}
}
// Using optional pattern
arrayMyEnum.contains {
if case .three(let user) = $0 {
return true
} else {
return false
}
}
或者正如您在注释中描述的那样,您不关心包装值,只是想检查实例是否为特定情况。然后您可以忽略包装值,
arrayMyEnum.contains {
switch $0 {
case .three:
return true
default:
return false
}
}
arrayMyEnum.contains {
if case .three = $0 {
return true
} else {
return false
}
}
我猜上面是你要求的。
通知,
具有包装值的底层枚举实例有一个哈希用于比较。因此,如果您想使用==
相等运算符执行相等,编译器会警告您您的枚举需要符合Hasable。
例如,如果你想比较,
enum MyEnum: Hashable {
case one
case two
case three(user: String)
}
MyEnum.three(user: "SomeValue") == MyEnum.three(user: "AnotherValue")
Swfit类型的枚举本身是可哈希的,是隐式可哈希的。
在您的情况下,具有包装值的枚举,包装值需要是可Has可处理的。由于String已经是Has可处理的,因此您只需要声明可散列一致性。
只有当包装类型不是Hasable时,您才需要自己编写==
和hasher
方法,这在大多数情况下非常简单。
读数
语言指南#枚举
语言参考#枚举大小写模式,可选模式。
据我所知,你想知道为什么你的转换声明
case (.three, .three):
return true
作品找到,但是
if array!.last.isOfType(.three) { /* ... */ }
导致编译器错误。
问题是由于开关语法有点特殊(模式匹配),不能在函数调用中使用。
由于您似乎想忽略user
的值,您可以执行以下操作:
if case .three = array!.last { /* ... */ }
这正是switch语句所做的-它忽略分配的值。
如果要调用函数,需要传入枚举的具体
实例,由于用户被isOfType
忽略,因此在以下语句中使用虚拟值将起作用:
if array!.last.isOfSameType(.three(user:"dummy")) { /* ... */ }