为什么 Scala 语言要求你初始化一个实例变量而不是依赖一个默认值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7291168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does Scala language require you initialize a instance variable instead of relying on a default value?
提问by Arthur Ronald
Scala language requires you initialize your instance variable before using it. However, Scala does not provide a default value for your variable. Instead, you have to set up its value manually by using the wildcard underscore, which acts like a default value, as follows
Scala 语言要求您在使用实例变量之前对其进行初始化。但是,Scala 不会为您的变量提供默认值。相反,您必须使用通配符下划线手动设置其值,其作用类似于默认值,如下所示
var name:String = _
I know, i know... I can define a constructor in the class definition, which takes as parameter our instance variable, so Scala does not force its initialization as shown below
我知道,我知道......我可以在类定义中定义一个构造函数,它将我们的实例变量作为参数,因此Scala不会强制其初始化,如下所示
class Person(var name:String)
However, i need to declare it in the body because i need to use a Java annotation whose ElementType is FIELD or METHOD; that is, it can just be applied to either a instance variable or method declared in the body of our class.
但是,我需要在正文中声明它,因为我需要使用 ElementType 为 FIELD 或 METHOD 的 Java 注释;也就是说,它可以只应用于我们类主体中声明的实例变量或方法。
Question: Why does Scala language require you initialize a instance variable - be it a default value _ or whatever you want - declared in the body of a class instead of relying on a default value ?
问题:为什么 Scala 语言要求你初始化一个实例变量——无论是默认值 _ 还是你想要的任何东西——在类的主体中声明而不是依赖于默认值?
采纳答案by Kris Nuttycombe
You canapply the annotation when you specify it as a constructor argument. Also, you may need to use a meta-annotation to restrict which target the annotation you're using is applied to - see http://www.scala-lang.org/api/2.10.2-RC2/index.html#scala.annotation.meta.package
您可以在将注释指定为构造函数参数时应用该注释。此外,您可能需要使用元注释来限制您正在使用的注释应用于哪个目标 - 请参阅http://www.scala-lang.org/api/2.10.2-RC2/index.html# scala.annotation.meta.package
Your question about "relying on a default value" is somewhat unclear, though. Initialization using an underscore corresponds to assigning the value of the variable to null. What other default are you thinking of?
不过,您关于“依赖默认值”的问题有些不清楚。使用下划线初始化对应于将变量的值分配给 null。你还想到什么其他默认值?
回答by agilesteel
If you use code like the following you are declaring, that the nameshould be abstract:
如果您使用如下声明的代码,则name应该是抽象的:
class A {
var name: String
}
I suppose you already knew that. So your question is rather of the syntactical nature. The answer is consistency with other possible abstract candidates.
我想你已经知道了。所以你的问题是句法性质的。答案是与其他可能的抽象候选者保持一致。
Suppose you want to do something like this:
假设你想做这样的事情:
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?)
}
The last three examples don't even compile. Now suppose you want to do something like this:
最后三个示例甚至无法编译。现在假设你想做这样的事情:
class A {
var variable: String
val value: String
def method: String
type theType
}
From my point of view, even someone who barely understands Scala seesonly declarations. There is no way to misinterpret them, because there is nothing there else than declarations. The one and only confusion arises when you come from another language and assume for a second that there are some default values. But this confusion is gone as soon as you see the first example (the one with the default values). And btw your class has to be a part of an abstract hierarchy in order to be allowed to declare abstract members, so even if you are new to the language you already get some extra help from the compiler.
在我看来,即使是几乎不了解 Scala 的人也只能看到声明。没有办法曲解它们,因为除了声明之外别无他物。当您来自另一种语言并假设有一些默认值时,会出现唯一的混淆。但是,一旦您看到第一个示例(具有默认值的示例),这种混乱就会消失。顺便说一句,您的类必须是抽象层次结构的一部分才能被允许声明抽象成员,因此即使您不熟悉该语言,您也已经从编译器那里获得了一些额外的帮助。
I hope this answers your question and happy coding.
我希望这能回答您的问题并祝您编码愉快。
回答by psp
Scala has no issue with "var name: String" in the class body. Did you try it? It doesn't mean what you want it to mean, though. It's an abstract var.
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) = () }

![Scala 将 List[Int] 转换为 java.util.List[java.lang.Integer]](/res/img/loading.gif)