swift - 可选键字典

标签 swift dictionary option-type

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

let dict: [Int?: Int] = [nil: 1]
// ERROR: type 'Int?' does not conform to protocol 'Hashable'

最佳答案

更新: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]

关于swift - 可选键字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44982414/

相关文章:

java - 对字符串数组进行分组和求和运算

python - 如何将字典的值(列表)与单独的列表进行比较?

javascript - 从 map 或其他方式返回值

ios - 展开可选时崩溃

ios - Swift UIViewController子类实例变量初始化策略

swift - 如何在 Swift 中获取 UIBezierPath 上的每个 CGPoint

ios - 加载新消息 Swift 4.2 和 Firebase

Java 8 可选而不是 if

ios - Swift:在 iPhone 上启用 "dismiss keyboard"按钮?

swift - 在 Swift 中实现一个协议(protocol)