如何解决CustomStringConvertible的重叠一致性

问题描述 投票:0回答:1

基于John Sundell的article,我具有以下结构:

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
    }
}

它可以是StringInt。为了能够简单地打印它(不需要使用.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)"
swift swift-protocols customstringconvertible
1个回答
0
投票

您可以使用单个CustomStringConvertible扩展名而不是当前使用的两个扩展名,而与类型无关:

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

对我来说,根据您上一个代码示例,此命令正确地先打印“字符串”,然后打印“ 5”。

这恰好是Sundell在他的Identifiable / Identifier的开源身份实现中所做的– 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

© www.soinside.com 2019 - 2024. All rights reserved.