2

I defined enums as confirming to a protocol Eventable:

protocol Eventable {
    var name: String { get }
    static var all: [Eventable] { get }
}

enum MyEnum: String, Eventable {
    case bla = "bla"
    case blu = "blu"

    var name: String {
        return self.rawValue
    }

    static var all: [Eventable] {
        return [
            MyEnum.bla,
            MyEnum.blu
        ]
    }
}

I have other enums like MyEnum also under the form: enum Bla: String, Eventable { }

I have two questions:

  1. for the enums having a String data type, I would like to avoid duplicating the generation of the variable name: var name: String I am not sure how to write that in Swift. I tried to play around with the "where" clause but not success. How can I achieve that?

  2. when I write my enums and conform to the protocol for that part: static var all: [Eventable] { get }. I would like that for the enum MyEnum, it constrains the variable to: static var all: [MyEnum] { ... } because for now I can put in the returned array any element being an Eventable and it's not what I need. Amongst other things, I tried to define a generic constraint in the protocol for it, but I get the following error:

Protocol 'Eventable' can only be used as a generic constraint because it has Self or associated type requirements

Thank you very much for the help!

2 Answers 2

1

For your second question, you just need to use Self:

protocol Eventable {
    var name: String { get }
    static var all: [Self] { get }
}

Self, similar to self, just means "the current type".

The first question is a little bit harder because you can't really get all the values of an enum safely. See here for more info. The closest I got was:

extension Eventable where Self: RawRepresentable, Self.RawValue == String {
    var name: String {
        return self.rawValue
    }
}

This means that you can omit the declaration of name in MyEnum, but not all.

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you for your answer :) For the first question it works like a charm. For the second question, I get the error I was mentioning (Protocol 'Eventable' can only be used as a generic constraint because it has Self or associated type requirements) when trying to use it.
@Toka If you think my answer answers your question, please consider accepting it by clicking on that checkmark!
I was editing my message when you answered, sorry. I still have the above mentioned problem for the second question. Do you have any idea why?
@Toka Did you use my exact code? Or did the error occur somewhere else, not in the extension? Basically, the error says that you can't use Eventable as a method parameter or the type of a variable anymore, because it has Self in it.
Yes I used the code your provided. For example I have a function with the following signature in a different object that triggers the error: func track(event: Eventable)
|
1

For the part of the question we need to extend Eventable protocol where Self inherits RawRepresentable

protocol Eventable {
    var name: String { get }
    static var all: [Self] { get }
}

extension Eventable where Self: RawRepresentable {
    var name: Self.RawValue {
        return self.rawValue
    }
}

enum MyEnum: String, Eventable {
    case bla = "bla"
    case blu = "blu"

    static var all: [MyEnum] = [bla, blu]
}

For the second part of your question we need to configure the function to handle a generic type

I would suggest making the function generic as well here is an example

func printEnum<T: Eventable>(_ event: T) {
    print(event.name)
}

and we can use it for any object confirms to Eventable

printEnum(MyEnum.bla)

1 Comment

Thank you for the answer, I'll give it a go :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.