Инициализировать структуру из данных в Swift 3

У меня есть Struct названный MyContiguousStruct чья память не имеет отступов.

struct MyContiguousStruct {
    let ivar1: UInt8
    let ivar2: UInt8
    let ivar3: UInt16
    let ivar4: UInt16
}

Мой инициализатор работает (отлично) так:

init?(data: Data) {
    guard data.count == MemoryLayout<Self>.size else { return nil }
    self = data.withUnsafeBytes { $0.pointee }
}

Я решил изменить ivar1тип от UInt8 перечислению с rawValue из UInt8 вот так:

struct MyContiguousStruct {
    let ivar1: EnumWithRawValueUInt8
    let ivar2: UInt8
    let ivar3: UInt16
    let ivar4: UInt16
}

но теперь я получаю то, что кажется инициализированным MyContiguousStruct, но ivar1 не является инициализированным перечислением. Я знаю, что я могу прочитать данные побайтно, то есть:

ivar1 = data[0]
ivar2 = data[1]
// ...

но это означает, что я не могу добавить это в протокол, который я могу прикрепить к непрерывно хранимым типам. Как я могу убедиться, что enum инициализирован?

1 ответ

Я считаю, что вам придется разобрать его вручную. Перечисления могут быть представлены необработанными значениями, но их лежащий в основе тип не является этим значением (как они есть в некоторых языках). Дополнительные возможности являются результатом соблюдения протокола RawRepresentable, а не путем изменения типа или хранения этого типа.

Если вы не хотите анализировать данные вручную, можно сделать ivar1 частные и имеют вычисленную собственность для вашего перечисления. Например

private let _ivar1: UInt8
var ivar1: EnumWithRawValueUInt8? {
    return EnumWithRawValueUInt8(rawValue: _ivar1)
}
Другие вопросы по тегам