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