Is there a way to write an `if case` statement as an expression?

后端 未结 3 621
隐瞒了意图╮
隐瞒了意图╮ 2021-02-01 17:13

Consider this code:

enum Type {
    case Foo(Int)
    case Bar(Int)

    var isBar: Bool {
        if case .Bar = self {
            return true
        } else {         


        
相关标签:
3条回答
  • 2021-02-01 17:24

    I have a similar wondering, and I kept searching for some work arounds about this, and landed on this page. I came up with code like this to compromise.

    fileprivate enum TypePrimitive {
        case foo
        case bar
    }
    
    enum Type {
        case foo(Int)
        case bar(Int)
        fileprivate var primitiveType: TypePrimitive {
            switch self {
            case .foo(_): return .foo
            case .bar(_): return .bar
            }
        }
        var isFoo: Bool { self.primitiveType == .foo }
        var isBar: Bool { self.primitiveType == .bar }
    }
    

    I hope Apple will provide better solution by adding some features in Swift language.

    0 讨论(0)
  • 2021-02-01 17:26

    Are you looking for the ? operator ?

    documentation is here under the Ternary Conditional Operator title.

    0 讨论(0)
  • 2021-02-01 17:34

    UPDATE 2: Another workaround... Create a var that returns an Int ONLY based on the case, then use a static (or instance, I thought static looked cleaner) method to test equivalence of just the case. It won't clash with Equatable, you don't have to overload an operator (unless you want to replace the static method with one), and you also wouldn't have to create separate var isFoo, var isBar, etc.

    I know you used this example to ask a more generic question (how can I use 'if case' as an expression?) but if that's not possible, this may be a valid workaround. I apologize if this treats "the symptoms" not "the problem"

    enum Something{
        case Foo(Int)
        case Bar(Int)
    
        static func sameCase(a: Something, b: Something) -> Bool {
            return a.caseValue == b.caseValue
        }
    
        var caseValue: Int {
            switch self {
            case .Foo(_):
                return 0
            case .Bar(_):
                return 1
            }
        }
    
        //if necessary
        var isBar: Bool {
            return Something.sameCase(self, b: Something.Bar(0))
        }
    }
    
    Something.sameCase(.Bar(0), b: .Foo(0)) // false
    Something.sameCase(.Bar(1), b: .Foo(2)) // false
    Something.sameCase(.Foo(0), b: .Foo(0)) // true
    Something.sameCase(.Bar(1), b: .Bar(2)) // true
    
    
    Something.Bar(0).isBar // true
    Something.Bar(5).isBar // true
    Something.Foo(5).isBar // false
    

    UPDATE 1:

    Ok, so this seems to work. If you overload the == operator to ignore values and return true only when both enums are the same case, you can pass any value in your isFoo method and still determine the type.

    I'm assuming you will need to customize this function to accommodate the the associated values, but it seems like a step in the right direction

    enum Something {
        case Foo(Int)
        case Bar(Int)
    
        var isFoo: Bool {
            return self == .Foo(0) // number doesn't matter here... see below
        }
    }
    
    func ==(a: Something, b: Something) -> Bool {
        switch (a,b) {
        case (.Bar(_), .Bar(_)):
            return true
        case (.Foo(_), .Foo(_)):
            return true
        default:
            return false
    
        }
    }
    
    let oneFoo = Something.Foo(1)
    let twoFoo = Something.Foo(2)
    let oneBar = Something.Bar(1)
    let twoBar = Something.Bar(2)
    
    oneFoo == twoFoo // true
    oneFoo == oneFoo // true
    oneFoo == oneBar // false
    oneFoo == twoBar // false
    

    OLD:

    You can use self and the case name to directly check which case it is, you don't have to use the case keyword. Hopefully this will work for your situation:

    enum Something{
        case Foo(Int)
        case Bar(Int)
    
        var isFoo: Bool {
            switch self {
            case Foo:
                return true
            case Bar:
                return false
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题