Измените «это» в функции расширения

Я хочу написать функцию расширения, которая модифицирует «это», например:

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

или

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

Возможно ли это в Котлине?

Я могу создать функцию расширения, которая возвращает измененное значение, но оставляет «это» неизмененным, но я хочу еще больше удобства! Похоже, Свифт может это сделать.

Ссылки на переменные еще не поддерживаются, но вы можете создавать функции расширения для использования со ссылками на свойства :

 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) 

Вы не можете этого сделать, потому что вам потребуется передать a по ссылке. Это невозможно в Котлине. Все аргументы функции в 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 

Как и любой другой параметр функции, 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}