Reputation: 33
I was trying to learn about swift basics and I encountered this problem:
Assume we have a dic:
var presidentialPetsDict = ["Barack Obama":"Bo", "Bill Clinton": "Socks", "George Bush": "Miss Beazley", "Ronald Reagan": "Lucky"]
And to Remove the entry for "George Bush" and replace it with an entry for "George W. Bush":
What I did:
var oldvalue = presidentialPetsDict.removeValueForKey("George Bush")
if let value = oldvalue
{
presidentialPetsDict["George W. Bush"] = value
}else
{
print("no matching found")
}
Because I believe removeValueForKey method will return an optional value in case key "George Bush" will not return a value but nil so we need to safely unwrap it by using if let. However, the solution code looks like this:
var oldValue = presidentialPetsDict.removeValueForKey("Georgee Bush")
presidentialPetsDict["George W. Bush"] = oldValue
The part I don't understand is that if we want to assign nil to a var we usually do this:
var value:String?
value = nil
But the solution code above works even though the method returns nil, could somebody explain why it worked because I think in solution we didn't declare oldValue as optional at all.
Upvotes: 3
Views: 1883
Reputation: 258
var oldValue = presidentialPetsDict.removeValueForKey("George Bush")
oldValue gets Optional String because of type inference of the return type.
See the function definition of removeValueForKey public mutating func removeValueForKey(key: Key) -> Value?
Upvotes: 1
Reputation: 59536
Since your array is defined as [String:String]
you wonder why the compiler let you assign an optional String
(so String?
) to a value.
How can the compiler risk you to put a nil
inside something that should be a non optional String ?
How can this code compile?
var oldValue: String? = presidentialPetsDict.removeValueForKey("Georgee Bush")
presidentialPetsDict["George W. Bush"] = oldValue
Subscript has the following logic, even if the value of the Dictionary
is String
, you can use subscript to assign nil
.
In that case the key is removed from the array.
Look here
var numbers: [String:Int] = ["one": 1, "two": 2, "three": 3]
numbers["two"] = nil // it looks like I'm putting nil into a Int right?
numbers // ["one": 1, "three": 3]
Upvotes: 2