Делаем классы кодируемыми

У меня есть протокол Codable и класс Codable:

public protocol SourceListItem: AnyObject, Codable
{
    var name: String { get set }
    var children: [SourceListItem] { get set }
}

final public class SourceListHeader: Codable
{
    var name: String = "Give me a name!"
    var children: [SourceListItem] = [SourceListItem]()
}

Однако компилятор дал мне две ошибки:

Type 'SourceListHeader' does not conform to protocol 'Decodable'
Type 'SourceListHeader' does not conform to protocol 'Codable'

Это почему? Не могу исправить ошибку, перепробовал множество вариантов ...

Кажется, проблема связана с протоколом, потому что, если я его удалю, все будет работать нормально. Это похоже на то, что компилятор не видит, что протокол применяется только к классам Codable.


person Adeline    schedule 25.06.2019    source источник


Ответы (1)


Вам нужен конкретный тип, соответствующий Codable, вы не можете использовать протокол, соответствующий Codable.

final public class SourceListHeader<Item: Codable>: Codable {
    var name: String = "Give me a name!"
    var children = [Item]()
}
person Dávid Pásztor    schedule 25.06.2019
comment
Это так хорошо ... спасибо. В чем разница между объявлением class SourceListHeader<Item: SourceListItem>:Codable и использованием var children: [Item] = [Item](), объявлением class SourceListHeader:Codable и использованием var children: [SourceListItem] = [SourceListItem](). Мне кажется, что <Item: SourceListItem> только сообщает компилятору, что Item соответствует _6 _..., что совпадает с var children: [SourceListItem] - person Adeline; 25.06.2019
comment
Item - это конкретный тип, соответствующий Codable, а SourceListItem - это протокол, унаследованный от Codable. Однако протоколы сами себе не соответствуют, отсюда и необходимость в дженериках. - person Dávid Pásztor; 25.06.2019