如何解决自定义字符串转换的重叠一致性



基于John Sundell的这篇文章,我有以下结构:

protocol Identifiable {
associatedtype RawIdentifier: Codable, Hashable = String
var id: Identifier<Self> { get }
}
struct Identifier<Value: Identifiable>: Hashable {
let rawValue: Value.RawIdentifier
init(stringLiteral value: Value.RawIdentifier) {
rawValue = value
}
}
extension Identifier: ExpressibleByIntegerLiteral
where Value.RawIdentifier == Int {
typealias IntegerLiteralType = Int
init(integerLiteral value: IntegerLiteralType) {
rawValue = value
}
}

它可以是字符串整数。为了能够简单地打印它(无需使用.rawValue(,我添加了以下扩展:

extension Identifier: CustomStringConvertible where Value.RawIdentifier == String {
var description: String {
return rawValue
}
}
extension Identifier where Value.RawIdentifier == Int {
var description: String {
return "(rawValue)"
}
}

问题是,它仅适用于符合CustomStringConvertible的扩展,而另一个被忽略。而且我无法将一致性添加到其他扩展,因为它们会重叠。

print(Identifier<A>(stringLiteral: "string")) // prints "string"
print(Identifier<B>(integerLiteral: 5)) // prints "Identifier<B>(rawValue: 5)"

无论类型如何,您都可以使用单个CustomStringConvertible扩展,而不是目前拥有的两个扩展:

extension Identifier: CustomStringConvertible {
var description: String {
"(rawValue)"
}
}

对我来说,根据您上一个代码示例,这正确打印了"字符串"然后"5"。

巧合的是,Sundell在他的开源身份实现中所做的 可识别/标识符 - https://github.com/JohnSundell/Identity/blob/master/Sources/Identity/Identity.swift#L72-L78

Point-Free的"标记"实现也值得参考:https://github.com/pointfreeco/swift-tagged/blob/master/Sources/Tagged/Tagged.swift

相关内容

  • 没有找到相关文章

最新更新