简体   繁体   中英

Swift Dictionaries: is it NOT possible to have an Array be the Value for a Key?

I wanna declare a couple of Arrays and assign them as the Values for Keys in a Dictionary.

Here's the code:

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.

This produces the following error:

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



So....

I tried modifying my Dictionary declaration like so:

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

And that gives me an even better error:

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


I tried all sorts of other fixes - nothing works.

This was/is a piece of cake in Objective-C, but in Swift...?

SOLUTION :
Moving the dictionary declaration statement into viewDidLoad fixed it:

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.

I don't quite get why that is, but it does work now.

In your code, you're not initializing colorsArray , numbersArray , and myDictionary so much as you are specifying a default value that will be used if init() does not set one. You're not allowed to reference other properties in the default value of a property, because (I'm speculating a bit) the order in which they are set is not guaranteed.

Something as simple as

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

fails in the same way your initial code did. To set c or myDictionary as desired, we must do so in an initializer, instead of using a default value:

class Test {

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

    init () {
        c = a*b
    }
}

(Note that immutable properties are mutable inside init , which is how we get away with using let c .)

So, the solution that most closely corresponds to your initial code is:

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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