a_tuo a_tuo - 10 months ago 52
Swift Question

Why the definition of ?? operator use @autoclosure?

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
in performance ?


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.