If-Let Assignment Operator

(AKA: A custom operator you will want to use)

How many times have you had to implement this pattern

if let value = someOptionalValue as? String {
  self.value = value
}

I use this all the time when parsing through JSON or implementing NSCoding and I think its a little over verbose for Swift, I felt sure there was a better way.

NSHipster mentions a logical OR assignment operator (||=) which would be perfect however, it doesn’t seem to be implemented for generics (Please let me know if I am wrong here). I thought I would give it a try…

infix operator ||= { associativity right precedence 90 }

func ||= (inout left: T, right: T?) {
    if let right = right {
        left = right
    }
}

It actually worked quite well, I was able to reduce the original code to this

self.value ||= someOptionalValue as? String

Might not be the biggest win, but when you have several of these assignments in a row, it saves a lot of code and makes it much more readable.

One more thing… and I am still trying to figure out exactly what is going on here, but I ended up having to define a second function to assign to optionals. The only difference is the left parameter now is T?

func ||= (inout left: T?, right: T?) { // The left param is now Optional
    if let right = right {
        left = right
    }
}

var someOptionalString: String?

someOptionalString ||= newValue // Will assign when newValue is not optional

If you are interested in seeing this in action, here is the Playground

** Note this was tested on Swift 2.0

UPDATE 11/01/2015:

I was notified by twitter that ||= is equal to left = left || right in ruby and what I am trying to do is left = right || left. I was not aware of this usage, to avoid confusion, I would  probably use another operator ?=.

infix operator ?= { associativity right precedence 90 }

func ?=<T>(inout left: T, right: T?) {
    if let value = right {
        left = value
    }
}

func ?=<T>(inout left: T?, right: T?) {
    if let value = right {
        left = value
    }
}