如何将枚举大小写传递给使用 'if case' 来检查 属性 大小写的函数
How to pass an enum case into a function that uses 'if case' to check for a property's case
我有一个枚举,其中每个案例都有不同的(或 none)关联值。枚举不可相等。
我在几个地方使用 if case
来检查某个值是否属于特定情况。
enum MyEnum {
case justACase
case numberCase(Int)
case stringCase(String)
case objectCase(NonEquatableObject)
}
let myArray: [MyEnum] = [.justACase, .numberCase(100), .stringCase("Hello Enum"), .justACase]
if case .justACase = myArray[0] {
print("myArray[0] is .justACase")
}
if case .numberCase = myArray[1] {
print("myArray[1] is .numberCase")
}
但我想将其提取到它自己的方法中,在该方法中我传递要检查的案例。我想象如下。 (有什么不明白的地方请在评论中写下。)
func checkCase(lhsCase: /*???*/, rhsCase: MyEnum) -> Bool {
if case lhsCase = rhsCase {
return true
} else {
return false
}
}
// Usage:
if checkCase(lhsCase: .justACase, rhsCase: myArray[0]) {
print("myArray[0] is .justACase")
}
在我上面的示例中,lhsCase 不应该是我假设的 MyEnum 类型,因为这意味着我将尝试比较两个属性(参见下面的代码)并要求我的枚举是可等式的。他们不是。
我不确定这样是否可行。
如果以下方法可行,它也能解决我的问题,但它没有。
if case myArray[3] = myArray[0] {
print("myArray[0] is .justACase")
}
有一个库 CasePaths 可以满足您的需求:像这样:
struct NonEO {
var a: Any
}
enum MyEnum {
case justACase
case numberCase(Int)
case stringCase(String)
case nonEO(NonEO)
}
let myArray: [MyEnum] = [.justACase, .nonEO(NonEO(a: 42)), .stringCase("Hello Enum"), .justACase, .nonEO(NonEO(a: "Thing"))]
func sameCase<T>(casePath: CasePath<MyEnum, T>,
lhs: MyEnum, rhs: MyEnum) -> Bool {
(casePath.extract(from: lhs) != nil)
&& casePath.extract(from: rhs) != nil
}
sameCase(casePath: /MyEnum.justACase, lhs: myArray[0], rhs: myArray[1]) // FALSE
sameCase(casePath: /MyEnum.justACase, lhs: myArray[0], rhs: myArray[3]) // TRUE
sameCase(casePath: /MyEnum.nonEO, lhs: myArray[1], rhs: myArray[4]) // TRUE
sameCase(casePath: /MyEnum.nonEO(.init(a: 42)), lhs: myArray[1], rhs: myArray[4]) // FALSE
of Shadowrun is a good start. Through the CasePaths library I found EnumKit,部分是 CasePaths 的灵感来源。然而,它提供了更简单的方法来比较案例。请参阅下面我的实现。
使用这个库有一些不错的好处,它允许具有关联值的枚举通过比较大小写并忽略值来变得相等。这可能并不总是需要的,但在很多情况下会派上用场。我用它来比较 ReSwift Actions 和我测试中的关联值。
import Foundation
import EnumKit
class NonEquatableObject {
}
enum MyEnum: CaseAccessible { // <-- conform to CaseAccessible
case justACase
case numberCase(Int)
case stringCase(String)
case objectCase(NonEquatableObject)
}
let myArray: [MyEnum] = [.justACase, .numberCase(100), .stringCase("Hello Enum"), .justACase]
if case .justACase = myArray[0] {
print("myArray[0] is .justACase")
}
if case .numberCase = myArray[1] {
print("myArray[1] is .numberCase")
}
func checkCase(lhsCase: MyEnum, rhsCase: MyEnum) -> Bool {
if case lhsCase = rhsCase {
return true
} else {
return false
}
}
// Usage:
if checkCase(lhsCase: .justACase, rhsCase: myArray[0]) { //<-- allows to pass variables or just the cases (unfortunately not without associated value.)
print("myArray[0] is .justACase")
}
if case myArray[3] = myArray[0] { //<-- allows this here too
print("myArray[0] is .justACase")
}
// Bonus: Adding equatable if associated values are not equatable. Looking at the case only.
extension MyEnum: Equatable {
static func == (lhs: MyEnum, rhs: MyEnum) -> Bool {
lhs.matches(case: rhs)
}
}
if myArray[3] == myArray[0] {
print("myArray[3] == myArray[0]")
}
我有一个枚举,其中每个案例都有不同的(或 none)关联值。枚举不可相等。
我在几个地方使用 if case
来检查某个值是否属于特定情况。
enum MyEnum {
case justACase
case numberCase(Int)
case stringCase(String)
case objectCase(NonEquatableObject)
}
let myArray: [MyEnum] = [.justACase, .numberCase(100), .stringCase("Hello Enum"), .justACase]
if case .justACase = myArray[0] {
print("myArray[0] is .justACase")
}
if case .numberCase = myArray[1] {
print("myArray[1] is .numberCase")
}
但我想将其提取到它自己的方法中,在该方法中我传递要检查的案例。我想象如下。 (有什么不明白的地方请在评论中写下。)
func checkCase(lhsCase: /*???*/, rhsCase: MyEnum) -> Bool {
if case lhsCase = rhsCase {
return true
} else {
return false
}
}
// Usage:
if checkCase(lhsCase: .justACase, rhsCase: myArray[0]) {
print("myArray[0] is .justACase")
}
在我上面的示例中,lhsCase 不应该是我假设的 MyEnum 类型,因为这意味着我将尝试比较两个属性(参见下面的代码)并要求我的枚举是可等式的。他们不是。
我不确定这样是否可行。
如果以下方法可行,它也能解决我的问题,但它没有。
if case myArray[3] = myArray[0] {
print("myArray[0] is .justACase")
}
有一个库 CasePaths 可以满足您的需求:像这样:
struct NonEO {
var a: Any
}
enum MyEnum {
case justACase
case numberCase(Int)
case stringCase(String)
case nonEO(NonEO)
}
let myArray: [MyEnum] = [.justACase, .nonEO(NonEO(a: 42)), .stringCase("Hello Enum"), .justACase, .nonEO(NonEO(a: "Thing"))]
func sameCase<T>(casePath: CasePath<MyEnum, T>,
lhs: MyEnum, rhs: MyEnum) -> Bool {
(casePath.extract(from: lhs) != nil)
&& casePath.extract(from: rhs) != nil
}
sameCase(casePath: /MyEnum.justACase, lhs: myArray[0], rhs: myArray[1]) // FALSE
sameCase(casePath: /MyEnum.justACase, lhs: myArray[0], rhs: myArray[3]) // TRUE
sameCase(casePath: /MyEnum.nonEO, lhs: myArray[1], rhs: myArray[4]) // TRUE
sameCase(casePath: /MyEnum.nonEO(.init(a: 42)), lhs: myArray[1], rhs: myArray[4]) // FALSE
使用这个库有一些不错的好处,它允许具有关联值的枚举通过比较大小写并忽略值来变得相等。这可能并不总是需要的,但在很多情况下会派上用场。我用它来比较 ReSwift Actions 和我测试中的关联值。
import Foundation
import EnumKit
class NonEquatableObject {
}
enum MyEnum: CaseAccessible { // <-- conform to CaseAccessible
case justACase
case numberCase(Int)
case stringCase(String)
case objectCase(NonEquatableObject)
}
let myArray: [MyEnum] = [.justACase, .numberCase(100), .stringCase("Hello Enum"), .justACase]
if case .justACase = myArray[0] {
print("myArray[0] is .justACase")
}
if case .numberCase = myArray[1] {
print("myArray[1] is .numberCase")
}
func checkCase(lhsCase: MyEnum, rhsCase: MyEnum) -> Bool {
if case lhsCase = rhsCase {
return true
} else {
return false
}
}
// Usage:
if checkCase(lhsCase: .justACase, rhsCase: myArray[0]) { //<-- allows to pass variables or just the cases (unfortunately not without associated value.)
print("myArray[0] is .justACase")
}
if case myArray[3] = myArray[0] { //<-- allows this here too
print("myArray[0] is .justACase")
}
// Bonus: Adding equatable if associated values are not equatable. Looking at the case only.
extension MyEnum: Equatable {
static func == (lhs: MyEnum, rhs: MyEnum) -> Bool {
lhs.matches(case: rhs)
}
}
if myArray[3] == myArray[0] {
print("myArray[3] == myArray[0]")
}