如何制定描述字符串表示的枚举的协议?

abj*_*ato 4 generics enums swift swift-protocols rawrepresentable

我有一个方法,它调用某个管理器的方法来用某个键保存 int 值。我的方法接收 int 和一些 EnumKey 枚举值作为键,挤出 EnumKey 的 rawValue 并将其作为字符串传递给管理器:

set(value: Int, forKey key: EnumKey) {
    SomeManager.saveIntValueWithStringKey(valueToSave: value, keyToSave: key.rawValue)
}

enum EnumKey: String { 
    case One="first key"
    case Two="second key"
}
Run Code Online (Sandbox Code Playgroud)

我想通过允许我的方法接收带有字符串原始值而不是 EnumKey 的每个枚举来使其更加通用。在方法的实现中,我将关键参数的类型从 EnumKey 替换为 GenericKey 协议,并使 EnumKey 符合此协议:

 set(value: Int, forKey key: GenericKey) {
    SomeManager.saveIntValueWithStringKey(valueToSave: value, keyToSave: key.rawValue)
}

protocol GenericKey {
    var rawValue: String { get }
}

enum EnumKey: String, GenericKey { 
    case One="first key"
    case Two="second key"
}
Run Code Online (Sandbox Code Playgroud)

但这String, GenericKey看起来有点难看。我希望每个可表示字符串的枚举都能自动适应,而不需要提及它除了 RawRepresentable 和 String 原始类型之外还符合 GenericKey 协议。就像是:

protocol GenericKey: RawRepresentable {
    associatedtype RawValue = String
}
Run Code Online (Sandbox Code Playgroud)

但编译器说“协议只能用作通用约束,因为它具有 Self 或关联的类型要求”。

有什么简单的方法可以解释编译器协议仅描述具有 String 类型的 RawValue 的 RawRepresentable 事物?

Dan*_*iel 5

您可以将函数定义为泛型,并将泛型类型定义为RawRepresentableof RawValuetype String,如下所示:

class Test {
    func set<T: RawRepresentable>(value: Int, forKey key: T) where T.RawValue == String {
        print("value \(value), key: \(key.rawValue)")
    }
}

enum EnumKey: String {
    case One="first key"
    case Two="second key"
}

let t = Test()
t.set(value: 3, forKey: EnumKey.One) // prints "value 3, key: first key"
Run Code Online (Sandbox Code Playgroud)