我正在从快速数据块中读取设置,并希望将其填充到结构中以便于访问和键入正确性。是否有一种简洁的方法将值赋给结构成员?例如使用下标自我?
let settings : [UInt] = [5, 5, 121, 700, 108, 1452, 6655, 10]
struct Header {
var version : UInt8?
var options : UInt8?
var records : UInt16?
var timeout : UInt16?
var left : UInt16?
var right : UInt16?
var middle : UInt16?
var speed : UInt8?
init(values: [UInt]) {
let m = Mirror(reflecting: self)
var labels : [String] = []
for (n, _) in m.children {
labels.append(n!)
}
for (h, v) in zip(labels, values) {
print("\(h) -> \(v)")
self[h] = v //error: type 'Header' has no subscript members
}
}
}
let h = Header(values: settings)
跟进
感谢ColGraff的解决方案。
在我的情况下,数据来自多个地方,以数组的形式出现。以下将有所帮助
let settings : [UInt] = [5, 5, 121]
let labels : [Header.Keys] = [.version, .options, .records]
var data : [Header.Keys : UInt] = [:]
zip(labels, settings).forEach { data[$0] = $1 }
答案 0 :(得分:3)
广泛接受的做某事的方式是:
struct Header {
let version : UInt
let options : UInt
let records : UInt
}
// adds marshaling from a `Dictionary`
extension Header {
enum Keys: String { case version, options, records}
init?(settings: [Keys:UInt]) {
guard let version = settings[.version] else { return nil }
guard let options = settings[.options] else { return nil }
guard let records = settings[.records] else { return nil }
self = Header(version: version, options: options, records: records)
}
}
let data: [Header.Keys: UInt] = [.version: 5, .options: 5, .records: 121]
if let foo = Header(settings: data) {
print(foo) // Header(version: 5, options: 5, records: 121)
}
如果您愿意,可以使用Dictionary
甚至Array
替换String
之类的结构,但Dictionary
是您要求的非常自然的结构。有些人甚至使用JSON
字符串编码Dictionary
或Array
结构来执行此操作。
是的,您可以使用Mirror
以更自动的方式执行此类操作,但这可能会非常棘手并导致问题。编写更具体的编组数据的方法通常更安全。
更高级的用法和讨论在this chat room。
答案 1 :(得分:0)
替代启发式解决方案:
let settings : [UInt] = [5, 5, 121, 700, 108, 1452, 6655, 10]
enum Fields: String {
case version, options, records, timeout, left, right, middle, speed
}
struct Header {
var version : UInt8?
var options : UInt8?
var records : UInt16?
var timeout : UInt16?
var left : UInt16?
var right : UInt16?
var middle : UInt16?
var speed : UInt8?
init(values: [UInt]) {
let m = Mirror(reflecting: self)
var labels : [Fields] = []
for (n, _) in m.children {
labels.append(Fields(rawValue: n!)!)
}
zip(labels, values).forEach { l, v in
switch l {
case .version: self.version = UInt8(v)
case .options: self.options = UInt8(v)
case .records: self.records = UInt16(v)
case .timeout: self.timeout = UInt16(v)
case .left : self.left = UInt16(v)
case .right : self.right = UInt16(v)
case .middle : self.middle = UInt16(v)
case .speed : self.speed = UInt8(v)
default: ()
}
}
}
}
var h = Header(values: settings)
print(h.version)
h.version = 7
print(h.version)
现在,如果我只能弄清楚如何从结构中动态生成枚举...