Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I still need to unwrap Swift dictionary value?

Tags:

swift

optional

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.

like image 602
sonoluminescence Avatar asked Dec 02 '15 21:12

sonoluminescence


People also ask

What are the three different methods to remove key value pair from dictionary in Swift?

Removing Key-Value Pairs To remove a key-value pair from a dictionary, set the value of a key to nil with subscript syntax or use the . removeValue() method. To remove all the values in a dictionary, append . removeAll() to a dictionary.

How do I unwrap optional in Swift?

An if statement is the most common way to unwrap optionals through optional binding. We can do this by using the let keyword immediately after the if keyword, and following that with the name of the constant to which we want to assign the wrapped value extracted from the optional. Here is a simple example.

How do you check if a dictionary contains a value in Swift?

The contains() method returns: true - if the dictionary contains the specified key or value. false - if the dictionary doesn't contain the specified key or value.

How does dictionary work in Swift?

Swift 4 dictionaries use unique identifier known as a key to store a value which later can be referenced and looked up through the same key. Unlike items in an array, items in a dictionary do not have a specified order. You can use a dictionary when you need to look up values based on their identifiers.


1 Answers

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"
}
like image 158
0x416e746f6e Avatar answered Nov 11 '22 17:11

0x416e746f6e