0

我想要一个GenericThing带有模板参数的模板参数,它是可以明智地转换为字符串和从字符串转换的任何类型。

// ConvertsToAndFromString is a made up protocol here – what should I use instead?
struct GenericThing<Id: ConvertsToAndFromString> {
}

然后我应该能够使用GenericThing任何具有合理编码作为字符串的类型。例如,它应该适用于Int, String(嗯,dah),理想情况下,它应该适用于任何本身将转换为字符串和从字符串转换的RawRepresentable地方。RawValue

例子:

enum Tubbies: String {
  case dipsy
  case laalaa
  case po
}

// I'd like to be able to do this.
let genericThing = GenericThing<Tubbies>

我看不出如何轻松做到这一点。

我希望我可以使用LosslessStringConvertible而不是我的 make up ConvertsToAndFromString

我试过这个,它适用于Int等等。但它不适用于Tubbies. 我看不到让所有RawRepresentable地方RawValue: LosslessStringConvertible也符合LosslessStringConvertible.

4

2 回答 2

4

这就是您如何根据其RawRespresentable有条件地扩展:LosslessStringConvertibleRawValue

extension RawRepresentable where RawValue: LosslessStringConvertible {
    init?(_ rv: RawValue) {
        self.init(rawValue: rv)
    }

    var description: String { return self.rawValue.description }
}

这是在行动:

struct GenericThing<Id: LosslessStringConvertible> {

}

enum Tubbies: String, LosslessStringConvertible {
    case dipsy
    case laalaa
    case po
}

let genericThing = GenericThing<Tubbies>()
print(Tubbies.po is LosslessStringConvertible) // => true
于 2019-11-07T15:09:59.387 回答
0

至少在 Swift 5.2 中存在扩展RawRepresentable导致CodingKeys编译失败的问题。

public extension RawRepresentable where RawValue: LosslessStringConvertible {
    init?(_ rv: RawValue) { self.init(rawValue: rv) }
    var description: String { rawValue.description }
}

struct Test: Codable {
    public var test: String
    enum CodingKeys: String, CodingKey { // Error: Type 'Test.CodingKeys' does not conform to protocol 'CustomStringConvertible'
        case test = "foo"
    } 
}

我的解决方法是使用相同的策略显式添加一致性,它需要能够更改枚举但允许CodingKeys编译。

public protocol LosslessStringConvertibleEnum: LosslessStringConvertible, 
    RawRepresentable where RawValue: LosslessStringConvertible {}

public extension LosslessStringConvertibleEnum {
    init?(_ rawValue: RawValue) { self.init(rawValue: rawValue) }
    var description: String { rawValue.description }
}

enum Tubbies: String, LosslessStringConvertibleEnum {
    case dipsy
    case laalaa
    case po
}
于 2021-08-11T07:15:25.140 回答