1

The definition of ?? operator is:

public func ??<T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T

Why not use T instead of @autoclosure?

Like this:

func ??<T>(optional: T?, defaultValue: T) -> T {
    switch optional {
    case .some(let value):
        return value
    case .none:
        return defaultValue
    }
}

Edit: What's the benefit of @autoclosure in performance ?

a_tuo
  • 651
  • 7
  • 23
  • 3
    See: http://stackoverflow.com/a/38291740/1630618 – vacawama Sep 06 '16 at 12:35
  • @vacawama "In order to get a short-circuiting behavior" ?, What dose it mean? – a_tuo Sep 06 '16 at 13:24
  • 1
    Possible duplicate of [Confusing \`constant captured by a closure before being initalized\` error](http://stackoverflow.com/questions/38291580/confusing-constant-captured-by-a-closure-before-being-initalized-error) – Lætitia Sep 06 '16 at 14:11

1 Answers1

3

If you go with you proposed function

func ??<T>(optional: T?, defaultValue: T) -> T

the value for defaultValue will be computed and copied or referenced directly in the body of the function. Which in many cases is computationally more work IF we actually will never use this value.

For example:

var thatImage: UIImage? = somImage

lazy var image() -> UIImage {
    return UIImage(named:"imgName")
}

let newImage = thatImage ?? image()

In this case:

func ??<T>(optional: T?, defaultValue: T) -> T 

When compiler evaluates this thatImage ?? image(), it actually calls the image function and it does the work and returns the image. But in the end we will discard it because the first optional has a value in this case.

With the @autocolsure, we wont spend our time computing things we dont need. We defer the computation.

with this,

func ??<T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T

the compiler will deduce the expression to this thatImage ?? image() -- > thatImage ?? {return image() }

The statement literally becomes this.

??(thatImage, { return image() } )

and only inside the block if there is no value for the first parameter only then the compiler will invoke the block which then will do compute to get the image.

kandelvijaya
  • 1,545
  • 12
  • 20