3

New to Swift and saw code from Standford open course of Swift programming as below:

if pending != nil {
    acccumulator = pending!.binaryFunction(pending!.firstOperand,acccumulator)
    pending = nil
}

As I learn about unwrapping, pending, in this case, is ensured not to be nil inside if block, then why should I use ! to unwrap pending while using it?

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Alan Hoo
  • 445
  • 3
  • 12
  • 2
    Related: [Swift optional parameter not unwrapped](http://stackoverflow.com/questions/40290202/swift-optional-parameter-not-unwrapped) – Hamish Nov 07 '16 at 15:25

3 Answers3

4

Because the if check has no bearing on the code inside the block. In this example, you should instead use a let, like so:

if let nonNilPending = pending {
    acccumulator = nonNilPending.binaryFunction(nonNilPending.firstOperand,acccumulator)
    pending = nil
}

That way you avoid the force-unwraps.

ganzogo
  • 2,516
  • 24
  • 36
  • I'm awaring of this though I am still confused for Swift can infer many things, and why does its compiler is not able to figure out impossibility of nil for an optional variable within such situation? I assume concept of 'optional' in Swift is kind of ’null‘ in C++ ...Thus if could prevents inside block executing with nil or void or null variable. – Alan Hoo Nov 08 '16 at 13:30
4

Even though you know that pending is not nil, its type remains optional. The compiler does not treat it differently in various contexts (i.e. inside and outside if) so you have to use ! operator in both places.

Swift does offer you a mechanism to check for nil and unwrap in a single go with an if let construct, which presents a convenient alternative to forced unwrapping.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
2

Because even if you're in that if block, the compiler doesn't know that the variable is "unwrapped". On top of that, using the force unwrap is a bad idea. You would be better off unwrapping the variable in an if conditional and then using the constant you set it to. For example:

if let unwrappedPending = pending {
    accumulator = unwrappedPending.binaryFunction(...)
    pending = nil
}

By setting the optional pending to the constant, you're conditionally unwrapping it. Then you can use the constant with the security of knowing that the constant is not nil and you don't have to use !

CaldwellYSR
  • 3,056
  • 5
  • 33
  • 50