1

Attempting to change dictionary values in a lambda function and then expecting the updated values at the caller level.

let test = { (header: [String: Int]) -> Void in
    header.updateValue(header["width"]! * 10, forKey: "width")
    header.updateValue(header["height"]! * 10, forKey: "height")
}

test(header: ["width": 10, "height": 2])

print(header["width"]) // expecting 100
print(header["height"]) // expecting 20

Problem: It still shows 10 and 2 at the caller level.

Developer
  • 924
  • 3
  • 14
  • 30
  • By the way, it's much more natural to just use the subscript operator: `header["width"]! *= 10` – Alexander Apr 03 '19 at 01:46
  • will it change the values at the caller level? – Developer Apr 03 '19 at 01:49
  • 1
    Nope. Dictionaries are structs, which are always passed by value unless explicitly passed by reference using the `inout` keyword. However, all mutating operations on a dictionary will trigger a copy of the data if there's a chance it can impact someone else. See https://stackoverflow.com/a/43493749/3141234 That post talks about `Array`, but COW is also implemented for `String`, `Dictionary`, and `Set`. – Alexander Apr 03 '19 at 02:34
  • https://www.hackingwithswift.com/sixty/5/10/inout-parameters – RajeshKumar R Apr 03 '19 at 03:08

1 Answers1

1

Dictionaries are passed by value. You can declare the function as taking inout Dictionary if you need to update it in the caller, or you can capture it in the closure.

Catfish_Man
  • 41,261
  • 11
  • 67
  • 84
  • Thanks, help me with the syntax please for `inout`, i placed it before parameter type? – Developer Apr 03 '19 at 01:25
  • @Developer You'll have a bunch better experience learning Swift if you follow along a structured resource, rather than piecing parts together ad hoc. I'd recommend you start with the [language guide](https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html) – Alexander Apr 03 '19 at 01:45