[英]Swift protocol for things that convert to and from String
I'd like to have a GenericThing
with a template parameter that is any type that can sensibly be converted to and from a string.我想要一个带有模板参数的
GenericThing
,它是可以明智地转换为字符串和从字符串转换的任何类型。
// ConvertsToAndFromString is a made up protocol here – what should I use instead?
struct GenericThing<Id: ConvertsToAndFromString> {
}
I should then be able to use GenericThing
with any type that has a reasonable encoding as a string.然后,我应该能够将
GenericThing
与具有合理编码为字符串的任何类型一起使用。 For example, it should work for Int
, String
(well, dah), and ideally, any RawRepresentable
where the RawValue
itself will convert to and from a string.例如,它应该适用于
Int
、 String
(嗯,dah),理想情况下,适用于RawValue
本身将转换为字符串和从字符串转换的任何RawRepresentable
。
Example:例子:
enum Tubbies: String {
case dipsy
case laalaa
case po
}
// I'd like to be able to do this.
let genericThing = GenericThing<Tubbies>
I can't see how to easily do this.我看不出如何轻松做到这一点。
I was hoping I could use LosslessStringConvertible
instead of my made up ConvertsToAndFromString
.我希望我可以使用
LosslessStringConvertible
而不是我编造的ConvertsToAndFromString
。
I tried this, and it works for Int
and such.我试过这个,它适用于
Int
等。 But it doesn't work for Tubbies
.但它不适用于
Tubbies
。 I couldn't see a way to make all RawRepresentable
where RawValue: LosslessStringConvertible
also conform to LosslessStringConvertible
.我看不到让所有
RawRepresentable
的方法,其中RawValue: LosslessStringConvertible
也符合LosslessStringConvertible
。
This is how you extend RawRespresentable
to be conditionally LosslessStringConvertible
depending on its RawValue
:这就是您如何根据
RawValue
将RawRespresentable
扩展为有条件的LosslessStringConvertible
:
extension RawRepresentable where RawValue: LosslessStringConvertible {
init?(_ rv: RawValue) {
self.init(rawValue: rv)
}
var description: String { return self.rawValue.description }
}
Here it is in action:这是在行动:
struct GenericThing<Id: LosslessStringConvertible> {
}
enum Tubbies: String, LosslessStringConvertible {
case dipsy
case laalaa
case po
}
let genericThing = GenericThing<Tubbies>()
print(Tubbies.po is LosslessStringConvertible) // => true
Had an issue in Swift 5.2 at least where extending RawRepresentable
was causing CodingKeys
to fail compiling.在 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"
}
}
My workaround was to instead explicitly add conformance using the same strategy, it requires being able to change the enum but allows CodingKeys
to compile.我的解决方法是使用相同的策略显式添加一致性,它需要能够更改枚举但允许
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
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.