Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to write an extension function that changes the value of the object?

Tags:

kotlin

In my case I want to change a primitive - Boolean

I never liked the following type of code:

private var firstTime: Boolean = true
...

    if (firstTime) {
        // do something for the first time here
        firstTime = false
    }

would be nice if I could have an extension function like:

if (firstTime.checkAndUnset()) {
    // do something for the first time here
}

Is this possible?

like image 249
ycomp Avatar asked Feb 12 '17 07:02

ycomp


People also ask

How do you use an extension function?

Basically, an extension function is a member function of a class that is defined outside the class. For example, you need to use a method to the String class that returns a new string with first and last character removed; this method is not already available in String class.

What is extended function?

Extension functions are a cool Kotlin feature that help you develop Android apps. They provide the ability to add new functionality to classes without having to inherit from them or to use design patterns like Decorator.

What is the benefit of using the extension functions?

Advantages of using Extension Function It can be able to add functionality to a final class. It means the class do not need to be defined as a non-final class. It can be able to add functionality without sub-classing, which means the object reference and the its implementation can be mentioned in your base class.

What is true about extension functions in Kotlin?

Kotlin extension function provides a facility to "add" methods to class without inheriting a class or using any type of design pattern. The created extension functions are used as a regular function inside that class. The extension function is declared with a prefix receiver type with method name.


2 Answers

A solution that would work for properties is to write an extension function for mutable properties and then use it with the property reference. This code work with Kotlin 1.1:

fun KMutableProperty0<Boolean>.checkAndUnset(): Boolean {
    val result = get()
    set(false)
    return result
}

Usage:

class MyClass {
    private var firstTime = true

    fun f() {
        if (this::firstTime.checkAndUnset()) {
            println("First time")
        }
    }
}

fun main(args: Array<String>) {
    val c = MyClass()
    c.f() // First time
    c.f() //
}

(check the runnable demo)

This, however, will not work for local variables (at least not in Kotlin 1.1).


In Kotlin 1.0.x, bound callable references are not yet available, and the solution above can be rewritten to this somewhat clumsier code:

fun <T> KMutableProperty1<T, Boolean>.checkAndUnset(receiver: T): Boolean {
    val result = get(receiver)
    set(receiver, false)
    return result
}

MyClass::firstTime.checkAndUnset(this)
like image 153
hotkey Avatar answered Oct 05 '22 19:10

hotkey


Just create following property

private var firstTime: Boolean = true
    get() {
        return if (field) { //Note: field - is keyword in current context
            field = false 
            true
        } else false 
    }
    set(v) { field = v }

And usage as simple as

if (firstTime) {
    //It's first time
    //firstTime is false now
}
like image 33
Dima Rostopira Avatar answered Oct 05 '22 20:10

Dima Rostopira