Вложенные дети полностью независимы. Внешний словарь - [TaskKey:Any]
, поэтому внутренний массив может быть любого типа. Компилятору нужна некоторая информация о том, что такое .title
. Как только вы сделаете один из ключей явным с помощью TaskKey.title
, Swift выведет остальное.
Другой способ сделать это - использовать явное приведение (as [[TaskKey:Any]]
или эквивалентно as Array<[TaskKey:Any]>
), чтобы сообщить Swift внутренний тип:
let taskDescriptions : Array<[TaskKey:Any]> = [
[ .title : "Buy milk",
.completed : false ],
[ .title : "Sleep",
.completed : false,
.children :
[
// `TaskKey` is required here
[ .title : "Find a bed",
.completed : false
],
[ .title : "Wait",
.completed : false
]
] as [[TaskKey:Any]] ],
[ .title : "Dance",
.completed : false ]
]
Примечание: Упрощение работы компилятора Swift с помощью явного указания типов сократит время компиляции.
Попробуйте использовать struct
или class
:
Я не уверен, что словарь - лучший выбор структуры данных здесь. Возможно, вы захотите использовать struct
или class
:
class Task: CustomStringConvertible {
var title: String
var completed: Bool
var children: [Task]
var description: String { return "Task(title: \(title), completed: \(completed), children: \(children)" }
init(title: String, completed: Bool, children: [Task] = []) {
self.title = title
self.completed = completed
self.children = children
}
}
var taskDescriptions : [Task] = [
Task(title: "Buy milk",
completed: false
),
Task(title: "Sleep",
completed: false,
children:
[
Task(title: "Find a bed",
completed: false
),
Task(title: "Wait",
completed: false
)
]
),
Task(title: "Dance",
completed: false
)
]
Это будет гораздо проще получить, чем иметь дело с приведением Any
к нужному типу.
Преимущество использования class
здесь (над struct
) заключается в том, что оно позволяет легко обновлять внутренние задачи:
Например:
// Mark all of the children tasks of the second task as completed
for task in taskDescriptions[1].children {
task.completed = true
}