Matching enum value in switch when enum implements protocol

I have a protocol

protocol P { }

and it is implemented by enumeration

enum E: P {
    case a
    case b
}

So far so good.

I want to be able to receive instances Pand return a specific value if it is one of E(in the future there will be other enums / structures, etc. that implement P).

I tried this:

extension P {

    var value: String {
        switch self {
            case E.a: return "This is an E.a"
            default: return "meh"
        }
    }
}

But it does not compile

error: Temp.playground:14:16: error: enum case 'a' is not a member of type 'Self'
    case E.a: return "hello"

I also tried:

 case is E.a: return "This is an E.a"

which just gives this error:

 error: Temp.playground:14:19: error: enum element 'a' is not a member type of 'E'
     case is E.a: return "hello"
             ~ ^

I know I can do it like this:

switch self {
    case let e as E:
        switch e {
            case E.a: return "hello"
            default: return "meh"
        }
    default: return "meh"
}

but I really don't want to!

Is there any syntax or technique that I am missing?

+4
source share
3 answers

You need to map the type Ebefore you can test the value E.a, but this can be done in one expression:

extension P {    
    var value: String? {
        switch self {
        case let e as E where e == .a:
            return "hello"
        default:
            return nil
        }
    }
}
+5

P enum

,

extension P where Self == E {
    var value:String {
        switch self  {
        case .a  :
                return "A"
        case .b:
            return "b"

        }
    }
}

let e = E.a.value
print(e)

:

""

+1

You are using it incorrectly: if you expand P, you can only access members P, not to E.

I would not repeat the extension Pand add all the tags there Eusing casting, but expanded Eas follows:

protocol P { 
    var value:String { get }
}

// Default implementation
extension P  {
    var value: String { return ""  }
}

enum E: P {
    case a
    case b
}

extension E {

    var value: String {
        switch self {
            case .a: return "This is an E.a"
            default: return "meh"
        }
    }
}
0
source

Source: https://habr.com/ru/post/1693363/


All Articles