How to cast optional T? to T

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

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

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!

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:

  1. Only do something if it's not nil (if let, guard let, etc)
  2. Substitute a default value instead of nil (??)
  3. Assert that nil is impossible (for reasons that you otherwise can't express to the type system), using a force unwrap (!)
3 Likes

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

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

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.

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

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!