【问题标题】:Val cannot be reassigned a compile time error for a local variable in fun in Kotlin无法为 Kotlin 中 fun 中的局部变量重新分配 Val 的编译时错误
【发布时间】:2017-05-26 09:53:46
【问题描述】:

在有趣的交换中,我试图用 b1 更改 a1 的值,但它显示 “val 无法重新分配编译时错误”。如果我不能这样改变,那怎么可能呢?

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

注意:这只是一个示例,用于了解为什么我无法像在 Java 中那样重新分配局部变量。

【问题讨论】:

  • 附注:您的swap 函数根本不会做任何事情。
  • 函数参数是本地的,对它们的赋值(Java 中不禁止)不会改变函数之外的任何东西。此外,您可以将任意表达式传递给函数,例如。 G。 swap(9, 42)。此分配可能看起来令人困惑,因此在 Kotlin 中被禁止。

标签: parameters kotlin


【解决方案1】:

在 Kotlin 中,val 声明了 final、只读、引用 - 这正是编译器错误告诉你的内容

Val 无法重新分配

一旦为val 赋值,就无法更改。如果您希望能够重新分配它,您必须将其声明为 var

在 Kotlin 中,方法参数被隐式声明为 final val,因此您不能像在 Java 中那样重新分配它们。

但您代码中的核心错误是您试图交换方法参数。由于方法参数是通过值而不是通过引用传递的,因此您想要实现的目标在 Kotlin 中是不可能的(就像在 Java 中一样)。即使您在方法调用中重新分配参数,传递给该方法的原始变量也不会改变。

【讨论】:

  • 所以 Kotlin dosent 支持重新分配要更改的 args 值,为此我创建了一个新的 var temp = a1 temp = b1
  • 你能纠正这个答案吗? val 不是常量也不是不可变的,它是最终引用,使用可变/不可变可能会误导引用指向的内容。而且他的错误不是直接与 val 有关,而是与 Kotlin 中始终为 final 的参数有关。
【解决方案2】:

这里有两个误解:

首先,在 Kotlin 中,所有参数都是 final,并且无法更改。就像在 Java 中一样,final 引用不能更改。因此,在尝试重新分配 finalval 引用时会出现错误。

其次,由于您拥有对字符串的引用的副本,因此您的交换函数不会影响调用者的原始引用。您的交换功能在 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
    }
    

    【讨论】:

    • 如果我尝试更改/分配 val a1Swapped=b1 然后 a1Swapped=4 的值,它会显示相同的错误 val cannot be reassigned
    • 这不交换任何东西,在函数之外没有副作用。
    • 当然,我只是表明你不能重新分配函数参数
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-29
    • 1970-01-01
    • 2019-09-01
    • 2016-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多