编译:
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首先没有这个具有未定义变量的功能呢?
答案 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
:
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
修饰符。因此,当这样的成员没有定义时,它被认为是抽象的。这就是当你尝试在具体类中声明抽象成员时编译器抱怨的原因。