为什么可以在REPL中声明具有相同名称的变量?

时间:2014-03-31 21:14:10

标签: scala read-eval-print-loop

scala> val hi = "Hello \"e"
hi: String = Hello "e


scala> val hi = "go"
hi: String = go

在同一个REPL会话中,为什么它允许我声明具有相同名称的变量hi?

scala> hi
res1: String = go

scala> hi="new"
<console>:8: error: reassignment to val
   hi="new"
     ^

这个错误我明白我们不能重新分配val

2 个答案:

答案 0 :(得分:11)

REPL的有趣设计特征是您的两个定义被翻译为:

object A {
  val greeting = "hi"
}
object B {
  val greeting = "bye"
}

后续用法将导入最后一个定义:

object C {
  import B.greeting
  val message = s"$greeting, Bob."  // your code
}

您可以通过scala -Xprint:parser见证确切的包装策略:

object $iw extends scala.AnyRef {
  def <init>() = {
    super.<init>();
    ()
  };
  import $line4.$read.$iw.$iw.greeting;
  object $iw extends scala.AnyRef {
    def <init>() = {
      super.<init>();
      ()
    };
    val message = StringContext("", ", Bob.").s(greeting)
  }
}

答案 1 :(得分:2)

在第一段代码中,我相信这是REPL的“功能”,允许您重新定义hi。假设您正在构建REPL中的一小段代码,那么返回并更改先前的定义而不重写其他定义以使用不同的值可能会有所帮助。

使用error: x is already defined as value x进行编译时,以下代码会出现错误scalac

class Foo{
  val x = "foo"
  val x = "foo"
}

在第二段代码中,您尝试重新分配无法更改的val。这就是你所期望的。