Как я могу создать экземпляр кодируемой структуры?

#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:) , лучше сделать в as extension Stuff: Codable {} , который сохранит инициализатор memberwise для типа

2. Спасибо за ваш ответ. Проблема в том, что мне нужно будет настроить декодер и кодировщик.

3. @Manngo Если это так, то вам нужно реализовать init(title:,code:,items:) вручную. Обновлен ответ.