「this」を変更する拡張関数を書きたいとします。たとえば、次のようになります。
var a = false
a.toggle() // now a contains false
また
var a = 1
a.increment() // now a contains 2
Kotlinで可能ですか?
修飾された値を返す拡張関数を作成できますが、"this" は変更されませんが、さらに便利が必要です。Swift はそれができるようです。
「this」を変更する拡張関数を書きたいとします。たとえば、次のようになります。
var a = false
a.toggle() // now a contains false
また
var a = 1
a.increment() // now a contains 2
Kotlinで可能ですか?
修飾された値を返す拡張関数を作成できますが、"this" は変更されませんが、さらに便利が必要です。Swift はそれができるようです。
変数への参照はまだサポートされていませんが、プロパティ参照で使用する拡張関数を作成できます。
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)
関数の他のパラメーターと同様this
に、オブジェクトへの参照です。一方、var a
も同じオブジェクトへの参照です。したがって、基本的に、同じインスタンスを指す 2 つの参照があります。
var a = false
val this = a // a.toggle()
これらの参照の 1 つを操作して、もう 1 つを変更することはできません。それらは同じ値を持つ無関係な変数であり、それ以上のものではありません。
(理論上) できることは、オブジェクト自体を変更可能にすることです。
class MutableBoolean(val value: Boolean)
val a = MutableBoolean(false)
a.toggle()
fun MutableBoolean.toggle() {value = !value}
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