I've got Yet Another Protocol Question. Sorry, folks.
The Swift 5.1 manual describes creating a `Collection` where the `Element` is a simple protocol, but doesn't explain how to make a Collection where the Element is a protocol with an associatedtype. In my case it's a protocol `Playable` that requires conformance to `Identifiable`.
I am fine with requiring the `Identifiable.ID` type to be `Int` for all types which adopt `Playable`, but I don't know how to express that qualification/requirement. The bits hit the fan when I try to declare something to be `[Playable]`.
My playground code might make my question clear.
protocol Playable: Identifiable // DOESN'T WORK where ID: Int { // DOESN'T HELP associatedtype ID = Int // DOESN'T HELP var id: Int { get } func play() } struct Music: Playable { var id: Int func play() { print("playing music #\(id)") } } (Music(id: 1)).play() // displays: "playing music #1\n" class Game: Playable { var id: Int init(id: Int) { self.id = id } func play() { print("playing game #\(id)") } } (Game(id: 2)).play() // displays: "playing game #2\n" enum Lottery: Int, Playable { case state = 100 case church case charity var id: Int { return self.rawValue } func play() { print("playing lottery \(self) #\(self.rawValue)") } } Lottery.church.play() // displays: "playing lottery church #101\n" var stuff: [Playable] = [] // error: Protocol 'Playable' can only be used as a generic constraint because it has Self or associated type requirements stuff.append(Music(id: 10)) stuff.append(Game(id: 24)) stuff.append(Lottery.charity) stuff.map { $0.id }
My goal is to have different structs and classes conforming to Playable (and hence to Identifiable) able to live inside a Collection.