Swift Init не соответствует ожидаемому типу «Декодер»

На данный момент у меня есть структура, соответствующая Codable:

public struct Preference: Codable {

    public let id: String

}

Когда я пытаюсь инициализировать объект, используя следующее:

let preference = Preference(id: "cool")

Я получаю следующую ошибку:

Argument type 'String' does not conform to expected type 'Decoder'

Как я могу исправить эту проблему и правильно инициализировать структуру?


person Adam Cooper    schedule 09.01.2018    source источник
comment
Странно, что без проблем компилируется в моем Xcode 9.2.   -  person Martin R    schedule 09.01.2018
comment
Я тоже не могу это воспроизвести. Я подозреваю, что это не настоящий код. В какой строке появляется эта ошибка? Есть ли у Preference именно это свойство в вашем коде?   -  person Rob Napier    schedule 09.01.2018
comment
Запустите новый проект и попытайтесь создать минимально воспроизводимый пример.   -  person Martin R    schedule 09.01.2018
comment
@RobNapier Это реальный код, и ошибка возникает при попытке инициализировать объект.   -  person Adam Cooper    schedule 09.01.2018
comment
Возможно, вы автозаполнили let preference = Preference(from: "cool") ? Это даст вам эту ошибку. Может быть, вы забыли изменить его на правильный инициализатор или изменили его, а компилятор медленно догоняет? Может, попробовать чистую?   -  person ekreloff    schedule 09.01.2018
comment
@ekreloff, если вы используете инициализатор from:, который у вас есть, затем принудительно приведите строку, чтобы она соответствовала декодеру.   -  person Adam Cooper    schedule 09.01.2018
comment
Это компилируется и работает правильно. Должно быть что-то еще в вашей кодовой базе? Версия Xcode?   -  person picciano    schedule 09.01.2018
comment
@AdamCooper, я просто предлагаю обстоятельства, при которых может появиться эта ошибка.   -  person ekreloff    schedule 10.01.2018
comment
Итак, видимо, тип определен в фреймворке (модуле), а конструктор вызывается извне модуля? – Это было бы важной информацией, которую можно было бы добавить к вопросу.   -  person Martin R    schedule 10.01.2018


Ответы (1)


Когда структура создается без явного инициализатора

public struct Preference {
    public let id: String
}

он получает инициализатор internal init(id: String) бесплатно. Внутренний означает, что его использование из другой цели приведет к ошибке компилятора.

Добавление Decodable к вашей структуре также добавляет инициализатор public init(from: Decoder) к этой структуре.

Таким образом, начальная структура эквивалентна следующему

public struct Preference: Codable {
    public let id: String

    internal init(id: String) {
        self.id = id
    }

    public init(from: Decoder) {
        // generated decoding code
    }
}

Когда вы пытаетесь создать экземпляр с помощью Preference(id: "cool") из другой цели, есть только один общедоступный инициализатор: тот, у которого есть декодер. Компилятор пытается использовать его, приводя String к Decoder, но терпит неудачу.

Чтобы решить исходную проблему, вам нужно явно добавить инициализатор public init(id: String).

person Maxim Kosov    schedule 09.01.2018