Reputation: 9457
I want to share functionality between CatZoo
and DogZoo
since they're storing similar data under the hood but I also want them to know what they are so they can act on their specific data, as shown in the DogZoo.makeNoise()
method.
What is the correct type for AnimalStorageProtocol.storage
?
enum CatType: String {
case lion
case tiger
case panther
}
enum DogType: String {
case coyote
case domestic
case wolf
}
struct CatZoo: AnimalStorageProtocol {
private var storage: [CatType: Int] // it's a bonus if they can stay private
}
struct DogZoo: AnimalStorageProtocol {
private var storage: [DogType: Int]
func makeNoise() {
for (key, value) in storage {
switch key {
case .coyote:
print("\(value) yips!")
case .domestic:
print("\(value) barks!")
case .wolf:
print("\(value) howls!")
}
}
}
}
I thought I could define a generic enum type in the protocol but I haven't been able to get it to work.
protocol AnimalStorageProtocol {
// var storage: <RawRepresentable where RawRepresentable.RawValue == String: Int> { get set }
var storage: [RawRepresentable: Int] { get set }
}
extension AnimalStorageProtocol {
var isEmpty: Bool {
get {
for (_, value) in storage {
if value != 0 {
return false
}
}
return true
}
}
}
Upvotes: 2
Views: 3576
Reputation: 13266
There are two different way you could do it depending on what your requirements are.
If you don't require the type to be a enum, you can simply do
protocol AnimalStorageProtocol {
associatedtype AnimalType: Hashable
var storage: [AnimalType: Int] { get set }
}
This will allow any hashable type to be used.
If you require that the types can only be RawRepresentable
where the RawValue
is a String
you'll have to define another protocol that your animal types will have to conform to.
protocol AnimalType: Hashable, RawRepresentable {
var rawValue: String { get }
}
protocol AnimalStorageProtocol {
associatedtype Animal: AnimalType
var storage: [Animal: Int] { get set }
}
Then you just have to set your enum types to conform to the AnimalType
protocol.
enum CatType: String, AnimalType { ... }
enum DogType: String, AnimalType { ... }
Upvotes: 3