2

我有这两个功能,我正在尝试修改元素。其中一个编译,另一个说'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);
}
}
4

3 回答 3

6

类似于Kotlin 中函数参数是 final 的for,循环中使用的变量也是如此。本质上,写...

for (i in array) {
    ...
}

... 相当于在 Java 中执行此操作:

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

这有助于捕获一些常见错误,在这种情况下 - 如果编译器允许您 - 您将重新分配这个仅包含对真实元素的引用的局部变量,而不更改数组。用 Java 术语来说,你会这样做:

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

这个新值i是未使用的,它不会改变数组本身,当循环到来时,它会立即被下一个元素的值覆盖。

于 2018-05-22T11:50:27.970 回答
2

试试这个:

for(i:Int in 0 until this.size) {
    this[i] = "your value"
}
于 2019-02-11T23:50:06.630 回答
1

您混淆了对对象和对象本身的引用的可变性。

在第一个示例中,结构是可变的,但对它的引用是不可变的。您可以更改对象本身的结构,但不能更改引用指向的结构。

在第二个示例中,您尝试更改对对象的不可变引用,而不是对象本身。

如果你写

val i = obj

obj如果它是一个可变对象,它仍然可以被改变。i但是不能重新分配,因为引用不能改变。

于 2018-05-22T11:48:03.697 回答