是否有任何解决方法可以使用 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/