繁体   English   中英

如何在 Swift 中使用字典初始化结构

[英]How to initialize a struct with dictionaries in Swift

我想每次初始化一个带有字典的结构。 稍后,我将使用它的属性而不是字典的键和值——这似乎更容易。 但是,当我尝试下面的代码时,它告诉我“从初始化程序返回而不初始化所有存储的属性”和“1. 'self.one' 未初始化”和“2. 'self.two' 未初始化”。 我的问题是如何从字典初始化结构,以便我基本上有一个包含字典内容的结构? 或者如何将其转换为结构?

struct Blabla {
    var one: String
    var two: [Int]

    init(three: [String: [Int]]) {
        for i in three {
            self.one = i.key
            self.two = i.value
        }

    } ERROR! - Return from initializer without initializing all stored properties
}

struct Blabla { 变量一:字符串变量二:[Int]

init(three: [String: [Int]]) {
    one = ""
    two = []
    for i in three {
        self.one = i.key
        self.two = i.value
    }

} ERROR! - Return from initializer without initializing all stored properties

}

for in子句可能有零次运行,在这种情况下,结构属性将不会被初始化。 您必须提供默认值(如果确实需要,则发出致命错误)。

虽然我认为您的示例是纯合成的,但无需遍历数组,您可以将属性设置为其最后一个条目。

这段代码应该可以编译,但我觉得以这种方式初始化 Struct 是不安全的,因为:

  • 它假设您的字典中有值。
  • 您存储的属性将始终具有您循环访问的最后一个值。
  • 为了拉出值以满足编译器,您需要强制解包它们。 (通过 Dávid Pásztor 的放哨方法,可以避免这种情况)
struct Blabla {
    var one: String
    var two: [Int]

    init(three: [String: [Int]]) {
        self.one = three.keys.first!
        self.two = three[three.keys.first!]!
    }
}

let input = ["pizza": [1,2]]
let l = Blabla(three: input)

如果我是你,我会让你免费获得的成员初始化器做它的事情,并提供一个专门的初始化器来处理你将字典作为输入的情况,或者将解析移动到另一个函数/类/等......

问题是如果three是一个空的Dictionary ,实例属性onetwo不会被初始化。 此外,您在 for 循环的每次迭代中都覆盖了属性,编译器无法保证在编译时会有任何循环迭代,因此会出现编译器错误。

您可以通过检查字典是否实际包含至少一个键值对并将第一个键值对分配给您的属性来使初始化程序无法解决这个问题。

struct Blabla {
    var one: String
    var two: [Int]

    init?(three: [String: [Int]]) {
        guard let key = three.keys.first, let value = three[key] else { return nil }
        one = key
        two = value
    }
}

但是,您应该重新考虑您实际尝试实现的目标,因为在您当前的设置中,您的 init 输入值与结构的属性不匹配。

编译器错误很明显:如果字典为空,则永远不会初始化结构成员。 但是代码没有任何意义,因为字典的每次迭代都会覆盖值。

也许您的意思是将字典映射到结构数组

struct Blabla {
    let one: String
    let two: [Int]
}

let three = ["A":[1,2], "B":[3,4]]
let blabla = three.map{Blabla(one: $0.key, two: $0.value)}

print(blabla) // [Blabla(one: "A", two: [1, 2]), Blabla(one: "B", two: [3, 4])]

我发现当您初始化某个结构的空对象时,您可以使用它

var nameofvar = Blabla([:])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM