Val не может быть переназначена ошибка времени компиляции для локальной переменной в fun в Kotlin

Здесь в веселом обмене я пытаюсь изменить значение a1 с b1, но он показывает, что "val не может быть переназначена ошибка времени компиляции". Если я не могу так измениться, то как это можно сделать?

fun swap(a1: String, b1: String) {
   val temp = a1
   a1 = b1
   b1 = temp
}

Примечание. Это всего лишь пример, позволяющий понять, почему я не могу переназначить локальную переменную, как мы можем это сделать в Java.

Ответ 1

В Kotlin val объявляется окончательный, только чтение, ссылка - и это именно то, что сообщение компилятора сообщает вам с

Val не может быть переназначен

После присвоения значения val его нельзя изменить. Если вы хотите переназначить его, вы должны объявить его как var

В параметрах метода Kotlin параметры неявно объявляются как final val, поэтому вы не можете переназначить их так же, как на Java.

Но основная ошибка вашего кода заключается в том, что вы пытаетесь изменить параметры метода. Поскольку параметры метода передаются по значению, а не по ссылке, чего вы хотите достичь, невозможно в Котлине (так же, как это невозможно в Java). Даже если вы переназначаете параметры внутри метода, исходные переменные, переданные методу, не будут меняться.

Ответ 2

Здесь есть два недоразумения:

Во-первых, в Котлине все параметры final, и это не может быть изменено. Как и в Java, ссылка final не может быть изменена. Поэтому при попытке переназначить ссылку final или val вы получите сообщение об ошибке.

Во-вторых, поскольку у вас есть копия ссылки на String, ваша функция подкачки не повлияет на исходные ссылки вызывающего. Ваша функция обмена не будет работать и в 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

Ответ 3

Вы не можете изменить значение параметра функции, вместо этого создайте новые переменные для измененных значений:

fun swap(a1: String, b1: String) {
    val a1Swapped = b1
    val b1Swapped = a1
}