简体   繁体   English

如何使协议描述字符串可表示的枚举?

[英]How to make protocol describing string-representable enums?

I've got a method which calls method of some manager to save int value with some key. 我有一个方法,该方法调用某些管理器的方法以使用某些键保存int值。 My method receives int and some EnumKey enum value as a key, extrudes EnumKey's rawValue and passes it to a manager as a string: 我的方法接收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"
}

I want to make this more generic by allow my method to receive every enum with string raw value instead of EnumKey. 我想通过允许我的方法使用字符串原始值而不是EnumKey来接收每个枚举,从而使其更加通用。 In implementation of method I've replaced type of key parameter from EnumKey to GenericKey protocol, and made EnumKey conform this protocol: 在方法的实现中,我已将键参数的类型从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"
}

But this String, GenericKey looks kinda ugly. 但是这个String, GenericKey看起来很丑。 I want every string-representable enum to suit automatically without mentioning it conforms to GenericKey protocol in addition to RawRepresentable and String raw type. 我希望除RawRepresentable和String原始类型外,每个字符串可表示的枚举都自动适应,而无需提及它符合GenericKey协议。 Something like: 就像是:

protocol GenericKey: RawRepresentable {
    associatedtype RawValue = String
}

but compiler says "Protocol can be used only as a generic constraint because it has Self or associated type requirements". 但是编译器说“协议只能用作通用约束,因为它具有Self或关联的类型要求”。

What could be an easy way to explain compiler that protocol describes only RawRepresentable things with RawValue of String type? 有什么简单的方法可以解释编译器,该协议仅描述String类型的RawValue的RawRepresentable东西?

You can define the function as generic, and define the generic type as RawRepresentable with RawValue of type String , like this: 您可以将函数定义为泛型,并使用String类型的RawValue将泛型类型定义为RawRepresentable ,如下所示:

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"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM