Is there a possibility to only perform an assignment (e.g. to a non-optional property) if the right hand side is not nil? I am looking for a one-line form for:
if let unwrapped = funcThatReturnsOptional() {
object.nonOptionalProperty = unwrapped
}
The answer from @Sajjon could be improved by using an if let
to avoid reflection.
precedencegroup OptionalAssignment { associativity: right }
infix operator ?= : OptionalAssignment
public func ?= <T>(variable: inout T, value: T?) {
if let value = value {
variable = value
}
}
A single expression with the same effect as your code is
funcThatReturnsOptional().map { object.nonOptionalProperty = $0 }
but your code is definitely better readable.
Here the map()
method of Optional
is used and the closure is
executed only if the function does not return nil
.
There are various ways that aren't too unwieldy
Using ?? :
object.nonOptionalProperty = funcThatReturnsOptional() ?? object.nonOptionalProperty
Using a function :
func setNotNil<T>(inout variable:T, _ value:T?)
{ if value != nil { variable = value! } }
setNotNil(&object.nonOptionalProperty, funcThatReturnsOptional())
Using an operator :
infix operator <-?? { associativity right precedence 90 assignment }
func <-??<T>(inout variable:T, value:T?)
{ if value != nil { variable = value! } }
object.nonOptionalProperty <-?? funcThatReturnsOptional()
Using an extension :
extension Equatable
{ mutating func setNotNil(value:Self?) { if value != nil { self = value! } } }
object.nonOptionalProperty.setNotNil(funcThatReturnsOptional())
Okay, actually there is a way to achieve exactly this by introducing a new operator ?=
:
infix operator ?= { associativity right precedence 90 }
func ?= <T: Any> (inout left: T, right: T?) {
if let right = right {
left = right
}
}
By using ?=
defined as above you can actually assign an optional to a non-optional if the optional has a value inside.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With