NEW: My new book Pro SwiftUI is out now – level up your SwiftUI skills today! >>

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 Play

SPONSORED Play is the first native iOS design tool created for designers and engineers. You can install Play for iOS and iPad today and sign up to check out the Beta of our macOS app with SwiftUI code export. We're also hiring engineers!

Click to learn more about Play!

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.