WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

SOLVED: Why Array unwrapping is not needed

Forums > 100 Days of Swift

Hello, I am trying to understand logic behind unwrapping optionals... I know, I have to unwrap dictionary key/value pair because swift always return an optional value

why does not the same apply to arrays? what is the reason behind this logic?

let names = ["Carl", "Amy"]
let dictionary = ["wtf": "what true false"]

print(dictionary["wtf"])  //Optional("what true false")
print(names[0])           //Carl

thanks

   

Because you declared your array with non-optional Strings. On the other hand, the key you ask for in the dictionary couldn't exist.

Declare your Array with var names: [String?] = [nil, "Carl", "Amy"] and you should see a different result. With your definition of names Swift declares your Array implicitly as [String].

   

@Hatsushira yeah, I understand this, but... My question is more like what thinking is behind this architecture of swift... Why is dicitonary always optional but array only if i declare it? Like those two feels kinda same in some ways (both conform to Collection protocol), yet array items are not optional by default.

   

A dictionary is an array of key: value pairs. If you try accessing a dictionary for a key that does not exist it will return nil.

For return type consistency (think of it as a return value from a function) the type returned from a dictionary has to be an optional. Whether it is a real value or nil, the return has to handle both.

In the case of arrays, you define whether the elements are optional or not. You will either allow a nil value, or not. Up to you.

Try this in Playground. Note: for the print statements you will see warnings that Int? has been coerced as Any.

var myDictionary: [String: Int] = [:]
myDictionary["One"] = 1
print (myDictionary["One"])
myDictionary["One"] = 2
print (myDictionary["One"])
print (myDictionary["Two"])
print (myDictionary)

You will see that the first print with the key "One" will print out 1, and the second print will be 2 (because the key was found in the the dictionary and the corresponding value was changed to 2.

The third print statement uses a key that does not exist in myDictionary, and so the value returned is nil.

The final print statement shows the whole of myDictionary, which in this case is ["One": 2].

   

I think that at least a portion of the answer you're looking for is that Swift does nothing to protect you from attempting to access an array element using a subscript that is out of bounds, i.e., less than zero or greater than the count of array elements minus one. If you do that, your app will crash. The result of accessing an array element is non-optional because the only alternative is a crash, not a nil result.

On the other hand, it's considered normal that you may not know whether a dict contains an element having a certain key, and that you want to test whether it does. Therefore, rather than crashing the program, accessing the value for a non-existent key returns nil, which tells you that such element does not exist.

   

Hacking with Swift is sponsored by Emerge

SPONSORED Why are Swift reference types bad for app startup time, and what’s the performance cost of protocol conformances? That’s just a couple of the topics you can learn about on the Emerge blog — written by the app performance experts behind Emerge’s advanced app optimization and monitoring tools, based on their experience of working at companies like Apple, Airbnb, Snap, and Spotify.

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.