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.