ここで楽しいスワップでは、a1の値をb1で変更しようとしていますが、valはコンパイル時エラーを再割り当てできないことを示しています。このように変更できない場合、どのように行うことができます。
fun swap(a1: String, b1: String) {
val temp = a1
a1 = b1
b1 = temp
}
注:これは、Javaでできるようにローカル変数を再割り当てできない理由を知るための単なるサンプルです
Kotlinでは、val
は最終的な読み取り専用の参照を宣言します。これは、コンパイラエラーがあなたに伝えていることです。
Valは再割り当てできません
val
に値を割り当てた後は、変更できません。再割り当てできるようにするには、var
として宣言する必要があります
Kotlinメソッドでは、パラメーターは暗黙的にfinal val
として宣言されるため、Javaでできるように再割り当てすることはできません。
しかし、コードのコアエラーは、メソッドパラメーターを交換しようとしていることです。メソッドパラメーターは参照ではなく値で渡されるため、Kotlinでは達成したいことは不可能です(Javaでも不可能です)。メソッド呼び出し内でパラメーターを再割り当てしても、メソッドに渡される元の変数は変更されません。
ここには2つの誤解があります。
まず、Kotlinではすべてのパラメーターはfinal
であり、これは変更できません。 Java a final
参照は変更できないため、final
またはval
参照を再割り当てしようとするとエラーが発生します。
次に、文字列への参照のコピーがあるため、スワップ関数は呼び出し元の元の参照に影響を与えません。スワップ関数は、Javaでも動作しません。
たとえば、コードを呼び出しても何も起こりません。
val s1 = "howdy"
val s2 = "goodbye"
swap(s1,s2) // Java or Kotlin, doesn't matter
println(s1)
println(s2)
// output:
// howdy
// goodbye
そして、それをリテラルまたは式で確実に呼び出しても何も起こりません。
swap("happy","day") // what references is it supposed to be swapping?
呼び出し元と同じ参照を保持しているオブジェクト内のコンテンツのみを交換できます。スワップルーチンを作成するには、次のようにします。
data class MutablePair(var one: String, var two: String)
fun swap(pair: MutablePair) { // not thread safe
val temp = pair.one
pair.one = pair.two
pair.two = temp
}
あなたはどちらを呼び出すことができます:
val stringies = MutablePair("howdy", "goodbye")
println("${stringies.one} ${stringies.two}")
swap(MutablePair()
println("${stringies.one} ${stringies.two}")
// output:
// howdy goodbye
// goodbye howdy
関数パラメーターの値を変更することはできません。代わりに、スワップされた値の新しい変数を作成します。
fun swap(a1: String, b1: String) {
val a1Swapped = b1
val b1Swapped = a1
}