Advanced Swift: Error Handling · Try/catch Basics | raywenderlich.com


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/1940818-advanced-swift-error-handling/lessons/3

@rayfix Could you please provide more details or link to the video for @autoclosure? I am not sure I have encountered it yet on RW. Thanks

If you have access to the RW book Expert Swift, you use auto closure in the first chapter to implement a hypothetical language feature.

Suppose you had this function:

func methodEager(value: Int) -> Int {
  if .random() {
    return value
  }
  return 0
}

If you call it like this:

func expensive() -> Int {
  42
}

methodEager(value: expensive() + 3)

Notice that expensive() is ALWAYS called even though half the time it doesn’t need to in order to return the answer 0.

To make this faster you can make it evaluate the parameter lazily using a closure. Rewrite the original function like this:

func methodLazy(value: () -> Int) -> Int {
  if .random() {
    return value()
  }
  return 0
}

The cool thing with this version is value never gets evaluated half the time.

Unfortunately you need to call it like this:

methodLazy(value: { expensive() + 3 } )

You need to throw in the extra set of { } to make it a closure.

That’s where auto closure comes in. Write it like this:

func methodLazyAuto(value: @autoclosure () -> Int) -> Int {
  if .random() {
    return value()
  }
  return 0
}

Now you can call it like this:

methodLazyAuto(value: expensive() + 3 )

The compiler inserts the {} for you. So you get the nice syntax at the call site like the first version but you still get lazy evaluation and the mentioned expensive only gets called if it has to.

Hope that helps
Ray

2 Likes

@rayfix This is brilliant! I love your style of explaining things with code. I will check out the Expert book. But for now, I am a happy girl and comfortable with the idea of autoclosure! Learn something new every day :slight_smile:

1 Like