Hi Swift Community,
Yesterday I tried this code:
func couldFailButWillNot() throws -> Any {
return 42
}
if let a = try? couldFailButWillNot() as? Int {
print(a)
}
And was surprised that the output was "Optional(42)” on both Swift 2.2 and Swift 3.
I always have the impression that when a variable is resolved with `if let` it will never be optional.
So, with a little investigation, I found out that it happens because `as?` has higher precedence than `try?` and is evaluated first.
And the whole expression `try? couldFailButWillNot() as? Int` evaluated as “Optional(Optional(42))”.
Also, I’m surprised that `try?` can be used with non-method-call.
This code: `print(try? 42)` will print “Optional(42)”.
So, the questions are:
1. Is it intentional that `try?` can be used with non-method-call and return an optional of the type that follows?
2. Should we design `try?` to have higher precedence than `as?`.
My intuition tells me that
`let a = try? couldFailButWillNot() as? Int`
and
`let a = (try? couldFailButWillNot()) as? Int`
should be equivalent.
3. Do you think that doubly-nested optional (or multi-level-nested optional) is confusing and should be removed from Swift? (Yes, I’ve seen this blog post [Optionals Case Study: valuesForKeys](Optionals Case Study: valuesForKeys - Swift Blog - Apple Developer <Optionals Case Study: valuesForKeys - Swift Blog - Apple Developer))
For me “Optional(nil)” (aka “Optional.Some(Optional.None))”) doesn’t make any sense at all.
Maybe, one of the solution is to always have optional of optional merged into a single level optional? Like Optional(Optional(Optional(42))) should be the merged to Optional(42).
Thank you
Sikhapol Saijit (Sam)
iOS Developer, Taskworld, Bangkok