如何对带有参数的枚举进行if-else比较 [英] How to do an if-else comparison on enums with arguments

查看:189
本文介绍了如何对带有参数的枚举进行if-else比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

语言:Swift2.3

Language: Swift2.3

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

For example let's I'll show you different kinds of enums

enum Normal {
    case one
    case two, three
}

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

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

Switch 可以在所有三个枚举都像这样:

Switch can be used on all three enums like so:

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语句上,尽管我只能对进行比较普通 NormalRaw ,并且显示 NormalArg 的错误消息,所以我不能运行代码

On the if-else statement though I can only do comparison for Normal and NormalRaw, and an error message shows for NormalArg, so I can't run the code


二进制运算符'=='不能应用于类型 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
}

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

Any Ideas? I'm not really doing anything with this code, I'm just wondering as to why we can't do comparison.

推荐答案

诀窍是实际上不使用==进行检查,而是在if语句中将 case 关键字与单个=结合使用。刚开始时这有点反常,但就像 if let 一样,您很快就习惯了:

The trick is to not actually check with == but rather use the case keyword in conjunction with a single = in your if statement. This is a little counter intuitive in the beginning but just like if let, you get used to it pretty fast:

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"
}

问题在于,在Swift中,如果枚举使用原始类型或没有关联,则只能免费获得枚举方程ed值(尝试一下,您不能同时拥有两个值)。但是Swift不知道如何将个案与关联的值进行比较-我的意思是怎么可能?让我们看这个例子:

The point is that in Swift you only get equation of enums for free if your enum uses a raw type or if you have no associated values (try it out, you can't have both at the same time). Swift however does not know how to compare cases with associated values - I mean how could it? Let's look at this example:

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...?

也许这样可以更清楚地说明为什么它不能开箱即用:

Maybe this makes it clearer why this cannot work out of the box:

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...?

因此,如果想要具有关联值的枚举,则必须通过以下方式在枚举中实现Equatable协议:自己:

So if you want enums with associated values, you'll have to implement Equatable protocol in your enum by yourself:

enum NormalArg: Equatable {
    case one(Int)
    case two

    static func ==(lhs: NormalArg, rhs: NormalArg) -> Bool {
        switch (lhs, rhs) {
        case (let .one(a1), let .one(a2)):
            return a1 == a2
        case (.two,.two):
            return true
        default:
            return false
        }
    }
}

这篇关于如何对带有参数的枚举进行if-else比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆