为什么Scala不能声明但是Java可以声明未定义的变量?

时间:2016-07-02 19:38:36

标签: java scala variables

编译:

public class SandboxJava { //Java
  public Integer cards;
}

但这不是:

class SandboxScala{
  var cards:Int //Throws saying the class must be abstract to have undefined variables
}

现在我知道必须初始化var的事实,但为什么Scala首先没有这个具有未定义变量的功能呢?

4 个答案:

答案 0 :(得分:2)

在Java中,尚未初始化未明确初始化的字段。引用自动初始化为null,标量值自动初始化为0。它不需要明确的事实只是一种速记或句法糖。

局部变量有点不同。它们不会自动初始化,并且可以在没有初始化的情况下声明它们,但在初始化它们之前访问它们是一个编译器错误。

public class Foo {
    public static void main(String[] args) {
        int x;
        if(x == 0) {
            System.out.println("Hello.");
        }
    }
}

结果

Foo.java:4: error: variable x might not have been initialized
        if(x == 0) {
           ^

答案 1 :(得分:2)

因为虽然它们看起来相似但它们意味着不同的东西(具有不同的“语义”)。 Scala等同于您的Java代码:

public class SandboxJava { // Java
  public Integer cards;
}

是这个Scala代码:

class SandboxScala {
  var cards:Int = _
}

这实际上与Java示例具有相同的语义。在上面的代码中cards

  • 可公开访问
  • mutable (因为var
  • 初始化为“默认值”(因为= _

请注意,正是因为cards 可变(一个var),您可以将cards初始化为其“默认值”。也就是说:val cards = _不起作用,原因显而易见(之后你无法更改val,所以最好用有意义的东西初始化它。)

正如其他答案所指出的那样,您的Scala版本是错误的(出于上述原因:您 使用 来初始化val)。

如果用这个更正了你的Scala版本:

class SandboxScala {
  val cards:Int = SOME_INITIAL_VALUE
}

你可以在Java中写一些语义相同的东西:

class SandboxJava {
  public final int cards = SOME_INITIAL_VALUE
}

请注意,如果您未能为cards提供初始值,则Java编译器会抱怨。

答案 2 :(得分:1)

val是不可变的。它永远不会被设置。一个永远无法设置的未初始化字段有什么用?

答案 3 :(得分:0)

Scala在abstract / def / val时没有var修饰符。因此,当这样的成员没有定义时,它被认为是抽象的。这就是当你尝试在具体类中声明抽象成员时编译器抱怨的原因。