Force Unwrap vs Optional chaining

Hi my question is about the difference between the Force unwrap (!) and the optional chaining (??), specifically in the context of the below line of code from the playground Hello World example.

let helloReference = capability!.borrow()
?? panic(“Could not borrow a reference to the hello capability”)

My understanding is that because the capability is optional, we use the force unwrap to abort the code in the case capability is nil. Then, what function does the ?? serve? I thought the ?? is what is referred to here as Nil-Coalescing Operator.

You are right, in that single line of code there are two optionals… the capability and the reference returned from borrowing the capability could also be nil

It might be easier to understand if you look at this variation of the example:

    let capability =<&HelloWorld.HelloAsset>(/public/Hello, target: /storage/GOODBYE) 
      ?? panic("Could not create link") 

    let helloReference = capability.borrow()
      ?? panic("Could not borrow a reference to the hello capability")

Thanks for the explanation and the code example, clear to me now!

1 Like

Thank you for this question, and sorry about the confusion here:

The result of getCapability used to be an optional, because an invalid path could be passed. This got improved a while ago, and now the result is non-optional, so the force-unwrap in your example is just a no-op now.

It’s important to note that getting a capability always succeeds, the capability is latent: only the borrow can fail, so it returns an optional.

Note that linking (function link) might also fail, i.e. it returns an optional, because the the given path might already exist.