Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.8k views
in Technique[技术] by (71.8m points)

swift - Get associated value from enumeration without switch/case

I've got an enumeration with a few different cases which are different types, e.g.

enum X {
    case AsInt(Int)
    case AsDouble(Double)
}

I can switch on these just fine to get the underlying value back out. However, the switch statement is highly annoying with trying to make me execute some code for the other cases that I simply don't care about. For example, right now I have something like

func AsInt(x: X) -> Int? {
    switch x {
    case AsInt(let num):
        return num;
    default:
        return nil;
    }
}

This works but it's pretty tedious always having to reference this method and having to write a new one for each case of each enumeration. What I'm looking for is how to simply attempt to cast a value of type X to one of the cases, like

var object: X = func();
let value = obj as? Int;
if value {
    // do shit
}

How can I simply check for a case without having to enumerate all of the cases about which I don't care and execute some non-statement for them?

Bonus points for any solution that can declare value as part of the conditional instead of polluting the scope.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are actually multiple ways to do it.

Let's do it by extending your enum with a computed property:

enum X {
    case asInt(Int)
    case asDouble(Double)

    var asInt: Int? {
        // ... see below
    }
}

Solutions with if case

By having let outside:

var asInt: Int? {
    if case let .asInt(value) = self {
        return value
    }
    return nil
}

By having let inside:

var asInt: Int? {
    if case .asInt(let value) = self {
        return value
    }
    return nil
}

Solutions with guard case

By having let outside:

var asInt: Int? {
    guard case let .asInt(value) = self else {
        return nil
    }
    return value
}

By having let inside:

var asInt: Int? {
    guard case .asInt(let value) = self else {
        return nil
    }
    return value
}

The last one is my personal favorite syntax of the four solutions.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...