2

The documentation doesn't seem to mention anything explicit about the order of optional chaining evaluation, just that:

Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil.

Might seem obvious but I needed to confirm exactly what happens and thought it might be helpful for others. e.g. are we able to safely do this kind of thing?

    opVar?.someObject.someMethod(opVar!)
sleep
  • 4,855
  • 5
  • 34
  • 51

1 Answers1

2

Optional chains are lazily evaluated left-to-right as you'd expect. The first optional in the chain to fail stops any further evaluation of the chain.

// Playground test for left-to-right lazy evaluation.
struct C {
    static var i = 0
    func chain(count: Int) -> C? {
        print("Expected \(count) -> \(C.i)")
        assert(count == C.i)
        C.i += 1
        return C.i > 2 ? nil : self
    }
}

let c = C()
c.chain(0)?.chain(1)?.chain(2)?.chain(3)!.chain(4)!

Output

Expected 0 -> 0
Expected 1 -> 1
Expected 2 -> 2
sleep
  • 4,855
  • 5
  • 34
  • 51
  • Are other operations evaluated right to left and only when it comes to optional chaining it's evaluated left to right? – mfaani Jul 26 '17 at 15:21
  • Generally things are evaluated left-to-right (obeying precedence rules), but the question is whether they are *lazily* evaluated. https://en.wikipedia.org/wiki/Lazy_evaluation – sleep Jul 31 '17 at 21:19