Kotlin - Val не может быть переназначен, но может быть переназначен путем доступа из индекса? - PullRequest
0 голосов
/ 22 мая 2018

У меня есть эти две функции, где я пытаюсь изменить элементы.Один из них компилирует, а другой говорит, что val не может быть переназначен.В чем разница между следующими функциями?Почему один компилируется, а другой нет?

Тот, который компилирует

fun <T> Array<T>.mapInPlace2(transform: (T) -> T) {
for (i in this.indices) {
    this[i] = transform(this[i])
}
}

Тот, который говорит

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

fun <T> Array<T>.mapInPlace1(transform: (T) -> T) {
for (i in this) {
    i = transform(i);
}
}

Ответы [ 3 ]

0 голосов
/ 22 мая 2018

Аналогично тому, как параметры функции являются окончательными в Kotlin , поэтому переменные используются в for циклах.По сути, запись ...

for (i in array) {
    ...
}

... эквивалентна выполнению этого в Java:

for (final int i : array) {
    ...
}

Это помогает выявить некоторые распространенные ошибки, в данном случае - еслиКомпилятор позволил вам - вы бы переназначили эту локальную переменную, которая просто содержит ссылку на реальный элемент, без изменения массива.В терминах Java вы должны делать это:

for (int i : array) {
    i = transform(i);
}

Это новое значение i не используется, оно не меняет сам массив, и оно будет немедленно перезаписано значениемследующий элемент, когда цикл возвращается.

0 голосов
/ 12 февраля 2019

Попробуйте это:

for(i:Int in 0 until this.size) {
    this[i] = "your value"
}
0 голосов
/ 22 мая 2018

Вы путаете изменчивость ссылок на объекты и сами объекты.

В первом примере структура изменчива, но ссылка на нее неизменна.Вы можете изменить структуру самого объекта, но вы не можете изменить структуру, на которую указывает ссылка.

Во втором примере вы пытаетесь изменить неизменную ссылку на объект, а не на объектсам по себе.

Если вы напишите

val i = obj

obj, он все еще может быть изменен, если это изменяемый объект.i не может быть переназначен, так как ссылка не может быть изменена.

...