'assign variable only if it is null

on Ruby one have something like this:

@var ||= 'value' 

basically, it means that @var will be assigned 'value' only if @var is not assigned yet (e.g. if @var is nil)

I'm looking for the same on Kotlin, but so far, the closest thing would be the elvis operator. Is there something like that and I missed the documentation?



Solution 1:[1]

The shortest way I can think of is indeed using the elvis operator:

value = value ?: newValue

If you do this often, an alternative is to use a delegated property, which only stores the value if its null:

class Once<T> {

    private var value: T? = null

    operator fun getValue(thisRef: Any?, property: KProperty<*>): T? {
        return value
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
        this.value = this.value ?: value
    }
}

You can now create a property that uses this like so:

var value by Once<String>()

fun main(args: Array<String>) {
    println(value) // 'null'
    value = "1"
    println(value) // '1'
    value = "2"
    println(value) // '1'
}

Note that this is not thread-safe and does not allow setting back to null. Also, this does evaluate the new expression while the simple elvis operator version might not.

Solution 2:[2]

Other way we could do it is by using ifEmpty..

From the docs: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/if-empty.html

Usage:

val empty = ""

val emptyOrNull: String? = empty.ifEmpty { null }
println(emptyOrNull) // null

val emptyOrDefault = empty.ifEmpty { "default" }
println(emptyOrDefault) // default

val nonEmpty = "abc"
val sameString = nonEmpty.ifEmpty { "def" }
println(sameString) // abc

EDIT: Seems like this does not work if the initial value is NULL and only for strings..

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2