如何在带参数的枚举上进行if-else比较

时间:2017-05-19 03:51:14

标签: swift enums

语言:Swift2.3

例如,让我向您展示不同类型的枚举

enum Normal {
    case one
    case two, three
}

enum NormalRaw: Int {
    case one
    case two, three
}

enum NormalArg {
    case one(Int)
    case two, three
}   

Switch可以在所有三个枚举中使用,如下所示:

var normal: Normal = .one
var normalRaw: NormalRaw = .one
var normalArg: NormalArg = .one(1)

switch normal {
    case .one: print("1")
    default: break
}

switch normalRaw {
    case .one: print(normalRaw.rawValue)
    default: break
}

switch normalArg {
    case .one(let value): print(value)
    default: break
}

在if-else语句中虽然我只能对NormalNormalRaw进行比较,并且显示NormalArg的错误消息,所以我无法运行代码

  

二元运算符'=='无法应用于NormalArg类型的操作数   和_

以下是代码示例:

if normal == .two { // no issue
    .. do something
}

if normalRaw == .two { // no issue
    .. do something
}

if normalArg == .two { // error here (the above message)
    .. do something
}

if normalArg == .one(_) { // error here (the above message)
    .. do something
}

if normalArg == .three { // error here (the above message)
    .. do something
}

任何想法?我真的没有对这段代码做任何事情,我只是想知道为什么我们不能做比较。

2 个答案:

答案 0 :(得分:66)

诀窍是不用==实际检查,而是在if语句中使用string first_section = str1.substr(0 , first_position) , second_section = str1.substr(first_position , second_position) , third_section = str1.substr(second_position, string::npos); 关键字和单个=。这在开始时有点直观,但就像case一样,你会很快习惯它:

if let

关键是,在Swift中,如果你的枚举使用原始类型或没有相关的值,你只能获得免费的枚举方程式(尝试一下,你不能同时拥有两者)。然而,Swift不知道如何将案例与相关值进行比较 - 我的意思是怎么样?我们来看看这个例子:

enum Normal {
    case one
    case two, three
}

enum NormalRaw: Int {
    case one = 1
    case two, three
}

enum NormalArg {
    case one(Int)
    case two, three
}


let normalOne = Normal.one
let normalRawOne = NormalRaw.one
let normalArgOne = NormalArg.one(1)

if case .one = normalOne {
    print("A normal one") //prints "A normal one"
}

if case .one = normalRawOne {
    print("A normal \(normalRawOne.rawValue)") //prints "A normal 1"
}

if case .one(let value) = normalArgOne {
    print("A normal \(value)") //prints "A normal 1"
}

也许这更清楚了为什么这不能开箱即用:

Normal.one == .one //true
Normal.one == .two //false

NormalRaw.one == .one //true
NormalRaw.one == .two //false

NormalArg.one(1) == .one(1) //Well...?
NormalArg.one(2) == .one(1) //Well...?
NormalArg.one(1) == .two //Well...?

因此,如果您希望枚举具有关联值,则必须自己在枚举中实现Equatable协议:

class Special {
    var name: String?
    var special: Special?
}

enum SpecialEnum {
    case one(Special)
    case two
}

var special1 = Special()
special1.name = "Hello"

var special2 = Special()
special2.name = "World"
special2.special = special1

SpecialEnum.one(special1) == SpecialEnum.one(special2) //Well...?

答案 1 :(得分:5)

答案是 Equatable Protocol

现在让我们看看它是如何运作的。

例如考虑这个枚举:

enum Barcode {
    case upca(Int, Int)
    case qrCode(String)
    case none
}

如果我们检查enum上的equatable运算符==,它将会失败。

// Error: binary operator '==' cannot be applied to two Barcode operands
Barcode.qrCode("code") == Barcode.qrCode("code")

如何使用Equatable Protocol解决这个问题?

extension Barcode: Equatable {
}

func ==(lhs: Barcode, rhs: Barcode) -> Bool {
    switch (lhs, rhs) {
    case (let .upca(codeA1, codeB1), let .upca(codeA2, codeB2)):
        return codeA1 == codeA2 && codeB1 == codeB2

    case (let .qrCode(code1), let .qrCode(code2)):
        return code1 == code2

    case (.None, .None):
        return true

    default:
        return false
    }
}

Barcode.qrCode("code") == Barcode.qrCode("code") // true
Barcode.upca(1234, 1234) == Barcode.upca(4567, 7890) // false
Barcode.none == Barcode.none // true