Reputation: 14500
I have a dictionary and printing dictionary key value as follow :
var student = ["name": "Alan Turing",
"age": "23",
"gender": "Male"
]
println(student["name"])
for item in student{
println("Student: \(item.0) = \(item.1)" )
}
if let name = student["name"]{
println(name)
}
The output looks like:
Optional("Alan Turing")
Student: gender = Male
Student: age = 23
Student: name = Alan Turing
Alan Turing
I wonder why optional value is printed for this line of code
println(student["name"]) ==> Optional("Alan Turing")
How this is different from for
and let
approaches and do I need to explicitly unwrap item value when accessing by key ? e.g
println(student["name"]!)
Upvotes: 0
Views: 51
Reputation: 27424
When you access a dictionary by subscripting it through a key (dict[key]
) if the key is not present the value returned is nil
. So the type of the result of student["name"]
is String?
to take into account the possibility of being nil
, and the result is an Optional(...)
.
In the other two cases instead (for
and if let
) the value is automatically unwrapped by the control structure, since it is not possible to have the value nil
as result, so that the type of item
is (String, String)
and not (String, String?)
, and the type of name
is String
.
So, if you use directly student["name"]
you should unwrap the optional value to get a String
(by using the different unwrapping operators).
Upvotes: 4
Reputation: 11803
You dictionary definitely has a value for "name" key and you know that, but compiler doesn't know that before it actually goes and checks for it. So when you are doing println(student["name"])
, compiler isn't sure if it will have value or not, hence considers it optional.
In case of your for-in
loop approach, compiler first extracts the keys and, hence, it is sure that these keys are present.
And if-let
automatically unwraps the value if it isn't nil, and hence it can't be optional.
Upvotes: 1