Reputation: 659
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 ?
Upvotes: 1
Views: 233
Reputation: 1585
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.
Upvotes: 3