[swift-evolution] Arrays Returning Optionals instead of Index Out of Bounds

Vladimir.S svabox at gmail.com
Tue Jun 7 12:54:32 CDT 2016


Yes, thank you Jeremy for pointing on this, my fault :-(, was confused by 
initial description of the problem in proposal and in my fast test I got 
"Optional(nil)" in console for existed "nil" value in dict, but didn't 
realized that it should be printed just "nil".

On 07.06.2016 19:06, Jeremy Pereira wrote:
>
>> IMO dictionary [Type1:Type2?] is a special case where you need to use myDict.keys.contains(keyValue) first to determinate if you have a value for key and after this you can get the value itself(which is Optional).
>
> I don’t understand why you think it is a special case. The return type of subscripting [ T1 : T2?] is T2?? or Optional<Optional<T2>>. You can do all the normal unwrapping you would expect except that one unwrapping results in another optional e.g.
>
> ---
> var sqrt: [Int : Int?] = [ 1: 1, 4 : 2, 2 : nil]
>
> func tellMeTheSquareRoot(n : Int) -> String
> {
>     if let lookupResult = sqrt[n]
>     {
>         if let theSquareRoot = lookupResult
>         {
>             return "\(n) has a square root and it is \(theSquareRoot)"
>         }
>         else
>         {
>             return "\(n) has a square root but it is not an integer"
>         }
>     }
>     else
>     {
>         return "I can't imagine what the square root of \(n) might be"
>     }
> }
>
> print(tellMeTheSquareRoot(4))
> print(tellMeTheSquareRoot(2))
> print(tellMeTheSquareRoot(-1))
>>
> gives the results
>
> 4 has a square root and it is 2
> 2 has a square root but it is not an integer
> I can't imagine what the square root of -1 might be
>
> Comparing to nil is ambiguous to the human eye but the compiler makes a decision
>
> sqrt[2] == nil // false (huh?)
> sqrt[-1] == nil // true
>
> The reason the first one is false is because the return result is not nil but
>
>  Optional<Optional<Int>>.Some(Optional<Int>.None>)
>
> A similar rule applies to assignment to a subscript, the compiler assumes the “top level” of optional but you can force the addition of an element with a nil value by being explicit.
>
> sqrt[2] = nil // [4: Optional(2), 1: Optional(1)] - 2 has been zapped
>
> sqrt[2] = Optional<Int>.None // [2: nil, 4: Optional(2), 1: Optional(1)] - 2 has been re-added
>
>
>


More information about the swift-evolution mailing list