可选键字典

时间:2017-07-08 04:11:31

标签: swift dictionary optional

是否有使用ref_db密钥创建字典的解决方法?我知道一个适当的解决方案需要实现条件一致性,但在此之前我有任何选择吗?

None

1 个答案:

答案 0 :(得分:1)

更新:Swift 4.2

Conditional conformances have been implemented in Swift 4.2,哇哦!

当包装元素为Optional时,这允许Hashable有条件地Hashable。因此,您可以直接使用任何Optional<T: Hashable>作为字典键!

let d: [Int?: String] = [
    nil: "nil",
    1: "a",
    2: "b",
    3: "c",
]

for (key, value) in d {
    let stringKey = key.map(String.init(describing:)) ?? "nil"
    print("\(stringKey): \(value)")
}

在Swift 4.2之前

我找到了一个解决方法:创建一个新的HashableOptional enum

enum HashableOptional<Wrapped: Hashable> {
    case none
    case some(Wrapped)

    public init(_ some: Wrapped) {
        self = .some(some)
    }

    public init(_ optional: Wrapped?) {
        self = optional.map{ .some($0) } ?? .none
    }

    public var value: Wrapped? {
        switch self {
            case .none: return nil
            case .some(let wrapped): return wrapped
        }
    }
}

extension HashableOptional: Equatable {
    static func ==(lhs: HashableOptional, rhs: HashableOptional) -> Bool {
        switch (lhs, rhs) {
            case (.none, .none): return true
            case (.some(let a), .some(let b)): return a == b
            default: return false
        }
    }   
}

extension HashableOptional: Hashable {
    var hashValue: Int {
        switch self {
            case .none: return 0
            case .some(let wrapped): return wrapped.hashValue
        } 
    }
}

extension HashableOptional: ExpressibleByNilLiteral {
    public init(nilLiteral: ()) {
        self = .none
    }
}

然后你可以这样使用它:

let dict: [HashableOptional<Int>: Int] = [nil: 1]