13

我想编写修改“this”的扩展函数,例如:

var a = false
a.toggle() // now a contains false

或者

var a = 1
a.increment() // now a contains 2

在科特林有可能吗?

我可以创建返回修改后的值的扩展函数,但不修改“this”,但我想要更方便!看起来 Swift 可以做到这一点。

4

3 回答 3

8

尚不支持对变量的引用,但您可以创建扩展函数以与属性引用一起使用:

fun KMutableProperty0<Boolean>.not() = set(get().not())
fun KMutableProperty0<Int>.inc() = set(get().inc())

var a = false
var b = 1

fun main(vararg args: String) {
    ::a.not()
    // now `a` contains `true`
    ::b.inc()
    // now `b` contains `2`
}

或者,如果您希望扩展函数在设置时返回新值:

fun KMutableProperty0<Boolean>.not(): Boolean = get().not().apply(setter)
fun KMutableProperty0<Int>.inc(): Int = get().inc().apply(setter)
于 2016-10-12T19:50:17.013 回答
2

您不能这样做,因为它需要您a通过引用传递给函数。这在 Kotlin 中是不可能的。Kotlin 中的所有函数参数都是按值传递的。

但是,您可以使用以下构造来模拟行为。虽然不是很方便。

fun Boolean.toggle(getter: () -> Boolean, setter: (Boolean) -> Unit) {
    setter(!getter())
}

var a = false

println(a) // prints false

a.toggle({a}, {a = it}) 
// Or a.toggle(a::get, a::set), but that isn't supported (yet?)

println(a) // prints true
于 2016-10-12T17:14:50.747 回答
2

与函数的任何其他参数一样,this是对对象的引用。另一方面,var a也是对同一对象的引用。所以基本上你有两个指向同一个实例的引用:

var a = false
val this = a  // a.toggle()

您无法对其中一个引用进行任何操作并更改另一个。它们是具有相同值的不相关变量,仅此而已。

您可以做的(理论上)是使对象本身可变:

class MutableBoolean(val value: Boolean)

val a = MutableBoolean(false)
a.toggle()

fun MutableBoolean.toggle() {value = !value}
于 2016-10-12T18:07:13.323 回答