#swift #struct #codable
#swift #структура #кодируемый
Вопрос:
Я хожу по кругу, пытаясь работать с кодируемой структурой. Я почти могу заставить его работать, но в конце я получаю сообщение об ошибке.
Вот простой пример:
struct Stuff: Codable {
var title: String = ""
var code: Int = 0
struct Item {
var name: String
var value: Int
}
var items: [Item] = []
init(from decoder: Decoder) throws { }
func encode(to encoder: Encoder) throws { }
}
var items: [Stuff.Item] = []
items.append(Stuff.Item(name: "Apple", value: 1))
items.append(Stuff.Item(name: "banana", value: 2))
var stuff = Stuff(title: "test", code: 23, items: items)
В этой последней строке я получаю сообщение об ошибке
Дополнительные аргументы в позициях # 1, # 2, # 3 в
Очевидно, что вложенная структура в порядке. Если я удалю :Codable
и init()
, и func encode()
это работает так, как я и ожидал.
Каков правильный способ сделать это?
Ответ №1:
Причина:
Поскольку вы внедрили init(from:)
инициализатор, значение по умолчанию init
недоступно.
Это причина, по которой он не может найти init(title:,code:,items:)
Решение:
Реализуйте инициализатор init(title:,code:,items:)
вручную. Кроме того, Item
Codable
также соответствует.
Теперь struct Stuff
должно выглядеть так,
struct Stuff: Codable {
var title: String = ""
var code: Int = 0
struct Item: Codable {
var name: String
var value: Int
}
var items: [Item] = []
init(from decoder: Decoder) throws { }
func encode(to encoder: Encoder) throws { }
init(title: String, code: Int, items: [Item]) {
self.title = title
self.code = code
self.items = items
}
}
Комментарии:
1. Также стоит отметить, что если кому-то действительно нужно реализовать
init(from:)
, лучше сделать в asextension Stuff: Codable {}
, который сохранит инициализатор memberwise для типа2. Спасибо за ваш ответ. Проблема в том, что мне нужно будет настроить декодер и кодировщик.
3. @Manngo Если это так, то вам нужно реализовать
init(title:,code:,items:)
вручную. Обновлен ответ.