Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot assign through subscript: 'dict' is a 'let' constant

Tags:

swift

I have a very simple problem with Swift. I created this function:

var dictAges : [String: Int] = ["John":40, "Michael":20, "Bob": -16]

func correctAges(dict:[String:Int]) {
     for (name, age) in dict {
          guard age >= 0 else {
          dict[name] = 0
          continue
          }
     }
}
correctAges(dict:dictAges)

But I don't understand the error:

"cannot assign through subscript: 'dict' is a 'let' constant, dict[name] = 0"

How can I solve it?

like image 525
Anna565 Avatar asked Nov 15 '17 15:11

Anna565


1 Answers

Input arguments to functions are immutable inside the function body and a Dictionary is a value type, so the dict you see inside the function is actually a copy of the original dictAges. When you call a function with a value type as its input argument, that input argument is passed by value, not passed by reference, hence inside the function you cannot access the original variable.

Either declare the dict input argument as inout or if you'd prefer the more functional approach, return a mutated version of the dictionary from the function.

Functional approach:

var dictAges : [String: Int] = ["John":40, "Michael":20, "Bob": -16]

func correctAges(dict:[String:Int])->[String:Int] {
     var mutatedDict = dict
     for (name, age) in mutatedDict {
          guard age >= 0 else {
              mutatedDict[name] = 0
              continue
          }
     }
     return mutatedDict
}
let newDict = correctAges(dict:dictAges) //["Michael": 20, "Bob": 0, "John": 40]

Inout version:

func correctAges(dict: inout [String:Int]){
    for (name,age) in dict {
        guard age >= 0 else {
            dict[name] = 0
            continue
        }
    }
}

correctAges(dict: &dictAges) //["Michael": 20, "Bob": 0, "John": 40]
like image 74
Dávid Pásztor Avatar answered Nov 18 '22 16:11

Dávid Pásztor