在Swift中,如何在协议扩展中使用通用枚举类型?

在Swift中,如何在协议扩展中使用通用枚举类型?,swift,enums,Swift,Enums,我想在CatZoo和DogZoo之间共享功能,因为它们在引擎盖下存储类似的数据,但我也想让它们知道它们是什么,以便它们可以对特定的数据进行操作,如DogZoo.makeNoise()方法所示 AnimalStorageProtocol.storage的正确类型是什么 enum CatType: String { case lion case tiger case panther } enum DogType: String { case coyote c

我想在
CatZoo
DogZoo
之间共享功能,因为它们在引擎盖下存储类似的数据,但我也想让它们知道它们是什么,以便它们可以对特定的数据进行操作,如
DogZoo.makeNoise()方法所示

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!")
            }
        }
    }
}
我想我可以定义一个泛型枚举类型,但我一直无法让它工作

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
        }
    }
}
协议动物存储协议{
//变量存储:{get set}
变量存储:[rawrrepresentable:Int]{get set}
}
扩展动物存储协议{
var isEmpty:布尔{
得到{
对于存储器中的(389;,值){
如果值!=0{
返回错误
}
}
返回真值
}
}
}

根据您的需求,您可以采用两种不同的方式来实现


如果不要求类型为枚举,只需执行以下操作即可

protocol AnimalStorageProtocol {
    associatedtype AnimalType: Hashable
    var storage: [AnimalType: Int] { get set }
}
这将允许使用任何哈希类型


如果您要求类型只能是
RawRepresentable
,其中
RawValue
字符串
,则必须定义您的动物类型必须遵守的另一个协议

protocol AnimalType: Hashable, RawRepresentable {
    var rawValue: String { get }
}

protocol AnimalStorageProtocol {
    associatedtype Animal: AnimalType
    var storage: [Animal: Int] { get set }
}
然后,您只需将枚举类型设置为符合
AnimalType
协议

enum CatType: String, AnimalType { ... }
enum DogType: String, AnimalType { ... }

回答得很好。我采用了第二种方法。使用这样的协议扩展非常有效:
var isEmpty:Bool{get{return storage.filter{$0.value!=0}.count==0}
static func==(lhs:Self,rhs:Self)->Bool{return lhs.storage==rhs.storage}