【问题标题】:Swift Dictionaries: is it NOT possible to have an Array be the Value for a Key?Swift 字典:不可能有一个数组作为键的值吗?
【发布时间】:2014-06-19 02:51:50
【问题描述】:

我想声明几个数组并将它们分配为字典中键的值。

代码如下:

class ViewController: UIViewController {
   let colorsArray = ["Blue", "Red", "Green", "Yellow"]
   let numbersArray = ["One", "Two", "Three", "Four"]

   let myDictionary = ["Colors" : colorsArray, "Numbers" : numbersArray]

   override func viewDidLoad() {
        super.viewDidLoad()
        // etc.

这会产生以下错误:

ViewController.Type does not have a member named 'colorsArray'



所以....

我尝试像这样修改我的字典声明:

let myDictionary:Dictionary<String, Array> = ["Colors" : colorsArray, "Numbers" : numbersArray]

这给了我一个更好的错误:

Reference to generic type 'Array' requires arguments in <...>


我尝试了各种其他修复方法 - 没有任何效果。

这在 Objective-C 中是小菜一碟,但在 Swift 中...?

解决方案
将字典声明语句移动到viewDidLoad 修复它:

class ViewController: UIViewController {
   let colorsArray = ["Blue", "Red", "Green", "Yellow"]
   let numbersArray = ["One", "Two", "Three", "Four"]

   override func viewDidLoad() {
        super.viewDidLoad()
        let myDictionary = ["Colors" : colorsArray, "Numbers" : numbersArray]
        // etc.

我不太明白为什么会这样,但它现在确实有效。

【问题讨论】:

  • work for me。试试这个let myDictionary:Dictionary&lt;String, Array&lt;String&gt;&gt; = ["Colors" : colorsArray, "Numbers" : numbersArray]
  • 我试过了!这是我尝试过的众多变体之一——因为它看起来正确——但我得到了同样的错误ViewController.Type does not have a member named 'colorsArray'这怎么可能?您是在 Playgrounds 中还是在实际的 Xcode 项目中这样做的?
  • 我在 REPL 中尝试过。您需要显示整个代码。我认为您在class Foo { /*code here*/ } 中有代码。但我只试过func foo() { /*code here*/}
  • 你所说的让我走上正轨 - 查看已编辑的问题。
  • 下面会有一些长答案,但简短的答案是,在所有属性都被赋值之前,你不能在初始化过程中使用 self 。因此,由于 myDictionary 仍未分配,因此您不能使用 self.colorsArray 对其进行初始化。

标签: arrays dictionary swift


【解决方案1】:

在您的代码中,您并没有初始化colorsArraynumbersArraymyDictionary,而是指定了一个默认值,如果init() 没有设置该默认值。不允许在属性的默认值中引用其他属性,因为(我推测)它们的设置顺序无法保证。

简单的事情

class Test {
    let a = 3
    let b = 5
    let c = a * b
}

以与您的初始代码相同的方式失败。要根据需要设置cmyDictionary,我们必须在初始化程序中这样做,而不是使用默认值:

class Test {

    let a = 3
    let b = 5        
    let c: Int

    init () {
        c = a*b
    }
}

(请注意,init 内部的不可变属性是可变的,这就是我们使用 let c 的方式。)

因此,与您的初始代码最接近的解决方案是:

class ViewController : UIViewController {
    let colorsArray = ["Blue", "Red", "Green", "Yellow"]
    let numbersArray = ["One", "Two", "Three", "Four"]

    let myDictionary: Dictionary<String, Array<String>>

    init() {
        myDictionary = ["Colors" : colorsArray, "Numbers" : numbersArray]
        super.init()
    }

    // etc
}

【讨论】:

  • 您的推测肯定很有趣 :-) 听起来确实合理。围绕 Swift 转转 - 经过多年的 Obj.C 是 - 好吧,没有乐趣! :-) (就像他们希望你如何称呼super.init() 你初始化你的变量......)成长的痛苦 - 这需要一点时间。已经弄清楚了,但是由于您花时间撰写答案,我会将您的答案标记为正确。干杯!
  • 谢谢。这也让我很烦恼。
猜你喜欢
  • 1970-01-01
  • 2017-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-01
  • 2013-01-17
  • 1970-01-01
相关资源
最近更新 更多