简体   繁体   中英

How to write Swift generic functions of enum types?

Using Swift, I want to write a protocol that specifies that implementing classes must have a function that takes an enum (which adheres to a given protocol), where that enum type is specified generically. I've tried this:

protocol Message {}

protocol Subscriber {
  func receive<T where T:Message>(message:T)
}

enum Greeting : Message {
  case Hello, Goodbye
}

class SomeObject : Subscriber {
  func receive<Greeting>(message: Greeting) {
    switch message {
    case .Hello:
      println("Hello")
    case .Goodbye:
      println("Goodbye")
    }
  }
}

This fails to compile with the message "Enum case pattern cannot match values of the non-enum type 'Greeting'" at each of the case lines. This would appear to be because the Subscriber protocol expects something that is no more specialized than Message, but I set things up in terms of Greeting, which though it implements Message, is more specialized. (Am I right?)

So, how do I do what I'm attempting to do, please?

The generic type parameter T should still be generic in the implementation of Subscriber . You can do what you ask using a typealias in protocol Subscriber and enforce the Message superclass constraint on it:

protocol Message {}

protocol Subscriber {
    typealias MessageType: Message
    func receive (message: MessageType)
}

enum Greeting : Message {
    case Hello, Goodbye
}

class SomeObject : Subscriber {
    typealias MessageType = Greeting

    func receive (message: MessageType) {
        switch message {
        case .Hello:
            println("Hello")
        case .Goodbye:
            println("Goodbye")
        }
    }
}

Having a generic receive prevents you from switching on the enum fields:

protocol Message {}

protocol Subscriber {
    func receive <T: Message> (message: T)
}

enum Greeting : Message {
    case Hello, Goodbye
}

class SomeObject : Subscriber {
    func receive <T: Message> (message: T) {

    }
}

let obj = SomeObject()
obj.receive(Greeting.Hello)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM