Scala分配vals

Geo*_*Geo 22 scala immutability

为什么不可能有这个:

def main(args:Array[String]) {
    val whatever:String // Have it uninitialized here

    if(someCondition) {
        whatever = "final value" // Initialize it here
    }
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么这不合法.我知道我可以做到var,但为什么我们必须val在我们宣布它时准确地初始化它?以后能够初始化它似乎更合乎逻辑吗?

Nic*_*tte 38

你可以做:

  val whatever =
    if (someCondition)
      "final value"
    else
      "other value"
Run Code Online (Sandbox Code Playgroud)


Kev*_*ght 29

Java解决方案实际上是一个问题的解决方法,并非所有表达式都返回值,因此您无法在Java中编写它:

final String whatever = if (someCondition) {
    "final value"
} else {
    "other value"
}
Run Code Online (Sandbox Code Playgroud)

越来越多的Java趋势是使用三元运算符:

final String whatever = someCondition ? "final value" : "other value"
Run Code Online (Sandbox Code Playgroud)

这对于有限的用例来说很好,但是一旦你开始处理switch语句和多个构造函数就完全站不住脚了.


斯卡拉的方法在这里有所不同.所有对象构造必须最终通过单个"主"构造函数,所有表达式都返回一个值(即使它是Unit,相当于Java的Void),并且构造函数注入非常受欢迎.这导致对象图被干净地构建为有向非循环图,并且对于不可变对象也非常好地工作.

您还要注意,在处理多个线程时,在单独的操作中声明和定义变量通常是一种不好的做法 - 并且在您最不期望它们时可能会让您容易暴露空值和竞争条件(尽管这不是在对象构造期间确实存在问题).不可变值的原子创建只是函数式语言帮助处理并发的方式的一个方面.

这也意味着Scala编译器可以避免Java语言规范中一些非常复杂的流分析.

如前所述,Scala Way™是:

val whatever =
  if (someCondition)
    "final value"
  else
    "other value"
Run Code Online (Sandbox Code Playgroud)

一种可扩展到其他控制结构的方法:

val whatever = someCondition match {
  case 1 => "one"
  case 2 => "two"
  case 3 => "three"
  case _ => "other"
}
Run Code Online (Sandbox Code Playgroud)

有了Scala的一点经验,你会发现这种风格有助于编译器帮助你,你会发现自己编写的程序有更少的bug!


Max*_* A. 9

使用lazy val如下:

def main(args:Array[String]) {
  lazy val whatever:String = if (someCondition) "final value" else "other value"

  // ...

  println(whatever) // will only initialize on first access
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*ise 7

除了其他人所说的,请注意Java允许"空白最终""变量",这是我有点想念的功能:

final Boolean isItChristmasYet;

if (new Date().before(christmas)) {
    isItChristmasYet = Boolean.FALSE;
} else {
    isItChristmasYet = Boolean.TRUE;
}
Run Code Online (Sandbox Code Playgroud)

但是,由于编译器中的数据流分析,如果不成功,javac将不允许您将whatever变量保留为未分配someCondition.

  • 出于好奇,你通过预先声明未初始化的变量获得了什么?在它实际初始化之前,它不是以任何方式使用它... (2认同)
  • `final boolean isItChristmasYet =有什么问题!(新的日期().之前(圣诞节))`? (2认同)