Вы можете добиться чего-то вроде этого с помощью хорошего 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
}
}
}
}
Это работает довольно хорошо (обратите внимание, что вам нужно, чтобы помочь быстры с типами, хотя):
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
}
Он также не по назначению, когда вы делаете вещи, которые не могут работать.
if let value: Int = dict["dict"] {
print(value) // is not executed
}
if let value: Int = dict["dict"]["nestedDict"]["nestedValue"] {
print(value) // is not executed
}
И вы даже можете установить значение в вложенных словарях, которые не были созданы еще !:
dict["dict"]["nestedDict2"]["nestedValue"] = 3
if let value: Int = dict["dict"]["nestedDict2"]["nestedValue"] {
print(value) // prints 3
}
После скольких словарей оно заканчивается? Или это словари на всем пути? – overactor
Да, это бесконечно. – Daniel
Уверенный, имеющий бесконечное гнездо словарей, означает, что вы никогда не храните никаких данных? Поскольку у вас будет строка для ключа, а затем другой словарь в качестве значения. Вы никогда не будете хранить ничего, кроме ключей. Я думаю, что, возможно, другая структура данных будет лучше подходит. Чего вы пытаетесь достичь? – Welton122