Using nil-coalescing operator with try? for function that throws and returns optional

Raunak

I want to use nil-coalescing operator to set a default value in both the following cases:

  1. function throws an error
  2. function returns nil

Please take a look at the code snippet below. I have the following questions:

  1. Why is item1 nil?
  2. What is the difference between the initialization of item1 vs item2
enum VendingMachineError: Error {
    case invalidCode
}

class VendingMachine {
    func itemCode(code: Int) throws -> String? {
        guard code > 0 else {
            throw VendingMachineError.invalidCode
        }
        if code == 1 {
            return nil
        } else {
            return "Item #" + String(code)
        }
    }
}

let machine = VendingMachine()

// Question: Why is this nil?
let item1 = try? machine.itemCode(code: 0) ?? "Unknown"
print(item1)
// nil

// What is the difference between the initialization of item1 vs item2
let item2 = (try? machine.itemCode(code: 0)) ?? "Unknown"
print(item2)
// Unknown

Sweeper

Essentially, this has to do with the grammar of the try operator. When used with a binary expression without brackets, try applies to the whole binary expression, so this:

try? machine.itemCode(code: 0) ?? "Unknown"

is the same as:

try? (machine.itemCode(code: 0) ?? "Unknown")

Since itemCode throws an error, the latter part of the expression ?? "Unknown is ignored, and the try? expression evaluates to nil.

On the other hand, the second expression is like this:

(try? machine.itemCode(code: 0)) ?? "Unknown"

The try? expression is evaluated first (to nil), then the ?? is applied, evaluating the whole expression to "Unknown".

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

What is the role of the nil-coalescing operator "??" in optional chaining?

Nil Coalescing Operator Swift

Nil coalescing operator for dictionary

Nil Coalescing Operator with mixed types

Swift nil coalescing operator with array

Left side of nil coalescing operator '??' has non-optional type 'String', so the right side is never used

Why is the nil coalescing operator ?? returning nil?

Why is Swift nil-coalescing returning an Optional?

Compiler not understanding Nil Coalescing Operator on NSTimeInterval

Nil-Coalescing Operator without changing value

How can I use try with the coalescing operator?

Type inference fails when using nil-coalescing operator with two optionals

Function throws AND returns optional.. possible to conditionally unwrap in one line?

iOS 12 SDK Generic function returns Optional.some(nil)

Swift: compile-time error with optional chaining and nil-coalescing

Safe destructuring using nullish coalescing or optional chaining

Optional value returning nil with ?? operator

Does null coalescing operator call a function twice?

Can an anonymous function be used with a null coalescing operator?

Coalescing Swift operator for an empty non-nil string

Why does the nil coalescing operator wrap an implicitly unwrapped default value?

Swift 4.2, Xcode 10.2 nil coalescing operator warning

using PHP's null coalescing operator on an array

Using pipe operator in function which returns Observable

The function returns nil

Is Nil-Coalescing always needed when using firstIndex(of: Character) in Swift?

Using An Objective-C Function that Returns an Optional or Throw in Swift

Why JSONDecoder always returns nil for an optional property?

Optional try for function with no return value