有没有办法编写一个更改对象值的扩展函数?

yco*_*omp 6 kotlin

在我的情况下,我想改变一个原语 - 布尔

我从不喜欢以下类型的代码:

private var firstTime: Boolean = true
...

    if (firstTime) {
        // do something for the first time here
        firstTime = false
    }
Run Code Online (Sandbox Code Playgroud)

如果我可以有一个扩展功能,那将是很好的:

if (firstTime.checkAndUnset()) {
    // do something for the first time here
}
Run Code Online (Sandbox Code Playgroud)

这可能吗?

hot*_*key 6

适用于属性的解决方案是为可变属性编写扩展函数,然后将其与属性引用一起使用.此代码适用于Kotlin 1.1:

fun KMutableProperty0<Boolean>.checkAndUnset(): Boolean {
    val result = get()
    set(false)
    return result
}
Run Code Online (Sandbox Code Playgroud)

用法:

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() //
}
Run Code Online (Sandbox Code Playgroud)

(查看runnable演示)

然而,这对局部变量不起作用(至少在Kotlin 1.1中不起作用).


在Kotlin 1.0.x中,绑定的可调用引用尚不可用,上面的解决方案可以重写为这个有点笨拙的代码:

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

MyClass::firstTime.checkAndUnset(this)
Run Code Online (Sandbox Code Playgroud)