Luiz E.
Luiz E.

Reputation: 7229

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?

Upvotes: 32

Views: 21954

Answers (2)

zekromWex
zekromWex

Reputation: 290

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..

Upvotes: 1

nhaarman
nhaarman

Reputation: 100358

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.

Upvotes: 56

Related Questions