Dan*_*iel 0 dictionary nested swift
我想建立一本字典的字典。在 Swift 中,如何声明一个具有字符串键和相同类型字典值的字典?我需要能够拥有无限的巢穴。(有点像使用节点构建树。只不过它不是树,而是字典。)
我尝试使用 AnyObject,但出现转换错误:
var node1: Dictionary<String, AnyObject?> = ["foo" : nil]
var node2: Dictionary<String, AnyObject?> = ["bar" : node1] // ERROR: Cannot convert value of type 'Dictionary<String, AnyObject?>' (aka 'Dictionary<String, Optional<AnyObject>>') to expected dictionary value type 'Optional<AnyObject>'
Run Code Online (Sandbox Code Playgroud)
是否有类型安全的方法来执行此操作(即不使用 AnyObject?)
您可以通过使用结构体和枚举,在 swift 中通过良好的 API 和类型安全来实现类似的功能。
enum RecursiveDictValue<KeyType: Hashable, ValueType> {
case Value(ValueType)
case Dict(RecursiveDict<KeyType, ValueType>)
}
struct RecursiveDict<KeyType: Hashable, ValueType> {
typealias OwnType = RecursiveDict<KeyType, ValueType>
private var dict: [KeyType: RecursiveDictValue<KeyType, ValueType>]
init() {
dict = [:]
}
init(dict: [KeyType: RecursiveDictValue<KeyType, ValueType>]) {
self.dict = dict
}
// this ensures that we can safely chain subscripts
subscript(key: KeyType) -> OwnType {
get {
switch dict[key] {
case let .Dict(dict)?:
return dict
default:
return RecursiveDict<KeyType, ValueType>()
}
}
set(newValue) {
dict[key] = .Dict(newValue)
}
}
subscript(key: KeyType) -> ValueType? {
get {
switch dict[key] {
case let .Value(value)?:
return value
default:
return nil
}
}
set(newValue) {
if let newValue = newValue {
dict[key] = RecursiveDictValue<KeyType, ValueType>.Value(newValue)
} else {
dict[key] = nil
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这非常有效(请注意,您需要帮助快速处理类型):
var dict = RecursiveDict<String, Int>(dict: ["value":.Value(1),
"dict":.Dict(RecursiveDict<String, Int>(dict: ["nestedValue": .Value(2)]))])
if let value: Int = dict["value"] {
print(value) // prints 1
}
if let value: Int = dict["dict"]["nestedValue"] {
print(value) // prints 2
}
Run Code Online (Sandbox Code Playgroud)
当您执行无法正常工作的操作时,它也会按预期失败。
if let value: Int = dict["dict"] {
print(value) // is not executed
}
if let value: Int = dict["dict"]["nestedDict"]["nestedValue"] {
print(value) // is not executed
}
Run Code Online (Sandbox Code Playgroud)
您甚至可以在尚未创建的嵌套字典中设置值!:
dict["dict"]["nestedDict2"]["nestedValue"] = 3
if let value: Int = dict["dict"]["nestedDict2"]["nestedValue"] {
print(value) // prints 3
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3926 次 |
| 最近记录: |