Kotlin - Val不能重新分配,但可以通过从索引访问来重新分配?

时间:2018-05-22 11:44:56

标签: arrays kotlin extension-function

我有这两个功能,我试图修改元素。其中一个编译,另一个说'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 :(得分:6)

类似于function parameters are final in Kotlin的方式,for循环中使用的变量也是如此。基本上,写下来......

for (i in array) {
    ...
}

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

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

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

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

i的这个新值未使用,它不会更改数组本身,并且当循环出现时,它将立即被下一个元素的值覆盖。

答案 1 :(得分:1)

您对引用对象和对象本身的可变性感到困惑。

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

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

如果你写

val i = obj
如果

obj是一个可变对象,它仍然可以被突变。 i无法重新分配,但正确的参考资料无法更改。

答案 2 :(得分:1)

尝试一下:

for(i:Int in 0 until this.size) {
    this[i] = "your value"
}