2011-09-03 66 views
19

Scala语言要求您在使用它之前初始化您的实例变量。但是,Scala不会为您的变量提供默认值。相反,你必须使用通配符下划线,这就像一个默认值手动设置它的值,如下为什么Scala语言要求您初始化实例变量而不是依赖默认值?

var name:String = _ 

我知道,我知道......我可以在类定义定义构造函数,这需要作为参数提供实例变量,所以斯卡拉不会强迫其初始化如下图所示

class Person(var name:String) 

但是,我需要声明它的身体,因为我需要使用Java注解,其的ElementType为字段或方法;也就是说,它可以应用于在我们的类的主体中声明的实例变量或方法。

问题:为什么Scala语言要求你初始化一个实例变量 - 是它,你需要有一个默认值_或任何 - 一类,而不是依靠一个默认值体中声明?

+2

Martin的偏好是我的猜测:-)至少它是明确的,额外的2个字符(4个空格)并不是非常令人生畏的。 Java(一种非常冗长的语言)让赋值被省略似乎很愚蠢。另外,说“构造函数参数”(不知道它们实际称为: - /)不是被强制初始化 - 它们当然是在对象被实例化时。 – 2011-09-03 04:45:51

回答

6

可以当你将它指定为构造函数的参数应用注解。另外,您可能需要使用元注释来限制您正在使用的注释的目标 - 请参阅http://www.scala-lang.org/api/2.10.2-RC2/index.html#scala.annotation.meta.package

但是,有关“依赖默认值”的问题尚不清楚。使用下划线进行初始化对应于将变量的值分配给null。你在想什么其他的默认设置?

+0

我知道下划线符号用于分配默认值。但是,我想知道为什么Scala不允许像var name:String(没有下划线赋值)之类的东西,而是在类体中声明的时候。你指出了我不知道的Scala(+1)的一个很好的特性。然而,它不能满足我的需求,因为我还需要一个无参数的构造函数,如果我在类定义中声明的构造函数中声明了实例变量 –

+4

需要赋值的原因是,我相信这样编译器可以区分一个抽象变量(它被编译为一对抽象方法)和一个具体的变量,这也需要在类文件中生成该字段。 –

4

Scala在类体中的“var name:String”没有问题。你试过了吗?尽管如此,它并不意味着你想要它的意思。这是一个抽象变种。

abstract class A { 
    var name: String 
} 
// some possible uses for abstract vars 
trait B { type T ; var name: T } 
class B1 extends B { type T = Int ; var name: Int = 5 } 
// hey, no storage 
class B2 extends B { type T = String ; def name = "abc" ; def name_=(x: String) =() } 
+0

如果我只是声明var name:String;当编译成一个.class文件时,Scala编译器会抱怨:变量名没有定义。所以我想知道,即使由于设计问题,为什么Scala不允许在没有声明其初始值的情况下在类体中使用var name:String;无论是默认值还是其他值 –

+1

你可以重读我的答案,你似乎已经忽略了。你在问为什么“抽象”存在?一个未实现的抽象成员意味着你不能实例化这个类。这是设计,就像在java中一样。 – extempore

18

如果你使用像你在声明下面的代码,该代码name应该是抽象的:

class A { 
    var name: String 
} 

我想你已经知道了。所以你的问题不是语法上的。 答案与其他可能的抽象候选一致。

假设你想要做这样的事情:

class A { 
    var variable: String = _ // variable has some default value (probably null) 
    val value: String = _ // value cannot have any default values, since it cannot be reassigned later. 
    def method: String = _ // method could return some default value (probably null) 
    type theType = _ // what should the default type be? (Any perhaps?) 
} 

最后三个例子甚至不编译。现在假设你想要做这样的事情:

class A { 
    var variable: String 
    val value: String 
    def method: String 
    type theType 
} 

从我的角度来看,即使有人勉强谁了解斯卡拉看到只声明。没有办法曲解它们,因为除了声明之外什么都没有。当你来自另一种语言并且假设有一些默认值时,唯一的混淆就产生了。但是,只要你看到第一个例子(具有默认值的例子),这种混淆就消失了。而且你的类必须是抽象层次结构的一部分才能被允许声明抽象成员,所以即使你对这个语言还不熟悉,你已经从编译器中获得了一些额外的帮助。

我希望这可以回答你的问题和快乐的编码。

+1

谢谢你的回答(+1) –

相关问题