danmihai
(Dan)
1
I know in Swift it's generally suggested to use the if let construct like:
var t: T? = nil
if let some = t {
....
}
But is there a way to simply cast the variable to the non-optional type? Like:
var t: T? = nil
let some = t as! T
I've tried that but it doesn't seem to work
Jumhyn
(Frederick Kellison-Linn)
2
What about this doesn't work? Since t here is nil, of course the program will crash (since t is, at runtime, not a T), but the following compiles and runs fine for me:
var t: Int? = nil
let some = t as! Int
we do get a warning that as! is inappropriate here, because this operation is idiomatically spelled with the force-unwrap operator:
var t: Int? = nil
let some = t!
Again, the code as written will crash, but if t does have a value, this will work to turn a T? into a T:
var t: Int? = 0
let some = t! // some has type 'Int', value '0'
1 Like
danmihai
(Dan)
3
Sure, I see, but why does
var t: Int? = 0
let newT = t as! Int
result in Xcode saying:
Forced cast from 'Int?' to 'Int' only unwraps optionals; did you mean to use '!'?
I mean what's the difference between that and:
let some = t!
AlexanderM
(Alexander Momchilov)
4
That's not really how this works.
Optionals weren't some inconvenience the Swift language designers threw your way that you should just try to rid yourself of in by any means.
They're intentionally made to make you pause and consider: "how should I handle nil here?" in a deliberate, compiler-checked way.
As @Jumhyn is hint at, there's basically three options:
- Only do something if it's not nil (
if let, guard let, etc)
- Substitute a default value instead of
nil (??)
- Assert that
nil is impossible (for reasons that you otherwise can't express to the type system), using a force unwrap (!)
3 Likes
AlexanderM
(Alexander Momchilov)
5
as! can do more generalized casts.
! is more succinct and specific to force unwrapping from T to T?.
When it is applicable, ! is preferable over as!, much like map is preferable over for. The non-generality adds clarity.
2 Likes
Jumhyn
(Frederick Kellison-Linn)
6
Yeah, that's the warning I mentioned in my previous post.
Functionally, they're no different, and it's just a warning so you can compile and run the as! version just fine. But because there's another shorter and more idiomatic way to spell the force-unwrap operation, the compiler takes that as a signal that you might have meant to do something else and presents a warning.
1 Like
danmihai
(Dan)
7
Hi Alexander, I know that and totally agree with you, the reason why I'm asking is actually different I want to do something like
t == nill ? some value : t casted to T
I don't. believe optionals are an inconvenience, I actually really like them, and I do understand why they are there.
AlexanderM
(Alexander Momchilov)
8
I believe you're looking for the nil coalescing operator.
t ?? "some value"
The nil-coalescing operator ( a ?? b ) unwraps an optional a if it contains a value, or returns a default value b if a is nil . The expression a is always of an optional type. The expression b must match the type that’s stored inside a .
The nil-coalescing operator is shorthand for the code below:
a != nil ? a! : b
5 Likes
danmihai
(Dan)
9
Thanks! That's true! I really didn't think of that, I didn't use the operator so much, so I sort of forgot about it. Thank you!