sonoluminescence sonoluminescence - 5 months ago 19
Swift Question

Why do I still need to unwrap Swift dictionary value?

class X {
static let global: [String:String] = [
"x":"x data",
"y":"y data",
"z":"z data"
]

func test(){
let type = "x"
var data:String = X.global[type]!
}
}


I'm getting the error:
Value of optional type 'String?' not unwrapped
.

Why do I need to use
!
after
X.global[type]
? I'm not using any optional in my dictionary?

Edited:

Even if
X.global[type]
may not exist for the type, force unwrapping will still crash on runtime. A better approach may be:

if let valExist = X.global[type] {
}


but Xcode is giving me the wrong idea by hinting about optional type.

Answer

Dictionary accessor returns optional of its value type because it does not "know" run-time whether certain key is there in the dictionary or not. If it's present, then the associated value is returned, but if it's not then you get nil.

From the documentation:

You can also use subscript syntax to retrieve a value from the dictionary for a particular key. Because it is possible to request a key for which no value exists, a dictionary’s subscript returns an optional value of the dictionary’s value type. If the dictionary contains a value for the requested key, the subscript returns an optional value containing the existing value for that key. Otherwise, the subscript returns nil...

In order to handle the situation properly you need to unwrap the returned optional.

There are several ways:

Option 1:

func test(){
    let type = "x"
    if var data = X.global[type] {
        // Do something with data
    }
}

Option 2:

func test(){
    let type = "x"
    guard var data = X.global[type] else { 
        // Handle missing value for "type", then either "return" or "break"
    }

    // Do something with data
}

Option 3:

func test(){
    let type = "x"
    var data = X.global[type] ?? "Default value for missing keys"
}
Comments