在Scala的空白…为什么这是可能的?

我在Scala中进行编码,并在Intellij中进行一些快速重构,当我偶然发现以下奇怪的事情时:

package misc

/**
 * Created by abimbola on 05/10/15.
 */
object WTF extends App {

  val name: String = name
  println(s"Value is: $name")
}

然后我注意到编译器没有抱怨,所以我决定尝试运行这个,我得到了一个非常有趣的输出

Value is: null
Process finished with exit code 0

有谁能告诉我为什么这样做?

编辑:

>第一个问题,值名称被赋予一个自身的引用,尽管它还不存在;为什么Scala编译器不会爆发错误?
>为什么赋值的值为空?

1.)为什么编译器不会爆炸

这是一个简化的例子。这个编译是因为通过给定类型可以推断出默认值:

class Example { val x: Int = x }

scalac Example.scala 
Example.scala:1: warning: value x in class Example does nothing other than call itself recursively
class Example { val x: Int = x }

这不编译,因为不能推断出默认值:

class ExampleDoesNotCompile { def x = x }

scalac ExampleDoesNotCompile.scala 
ExampleDoesNotCompile.scala:1: error: recursive method x needs result type
class ExampleDoesNotCompile { def x = x }

这里发生了什么

我的解释所以要注意:统一的访问原则踢了
对val的赋值调用访问器x(),它返回x的统一化值。
所以x被设置为默认值。

class Example { val x: Int = x }
                             ^
[[syntax trees at end of                   cleanup]] // Example.scala
package <empty> {
  class Example extends Object {
    private[this] val x: Int = _;
    <stable> <accessor> def x(): Int = Example.this.x;
    def <init>(): Example = {
      Example.super.<init>();
      Example.this.x = Example.this.x();
      ()
    }
  }
}                            ^

2.)为什么值为null

默认值由Scala编译到的环境决定。

在您给出的示例中,您看起来像在JVM上运行。 Object的默认值为null。

因此,当您不提供值时,默认值将用作回退。

默认值JVM:

byte  0
short 0
int   0
long  0L
float 0.0f
double    0.0d
char  '\u0000'
boolean   false
Object    null // String are objects.

此外,默认值是给定类型的有效值:
以下是REPL中的一个示例:

scala> val x : Int = 0
x: Int = 0

scala> val x : Int = null
<console>:10: error: an expression of type Null is ineligible for implicit conversion
val x : Int = null
                   ^
scala> val x : String = null
x: String = null
http://stackoverflow.com/questions/33042800/nulls-in-scala-why-is-this-possible

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:在Scala的空白…为什么这是可能的?