问题描述
在Scala中,如何在不是数据成员的类的主构造函数中定义一个局部参数,并且例如仅用于初始化基类中的数据成员?
例如,在下面的代码中,我如何正确定义 B类的主构造函数中的参数
b
类A(var a:Int)
B类(?b?)扩展A(b)
Randall,你的答案解释了为什么当我引入一个方法 inc
增加属性 a
,而且更改类 B
构造函数中的参数名称以匹配类 A中的参数的名称
构造函数:
class A(var a:Int)
class B Int)extends A(a){
def inc(value:Int){this.a + = value}
}
Scala编译器输出:
$ scala construct.scala
。 scala:3:错误:重新分配到val
def inc(value:Int){this.a + = value}
^
发现一个错误
Scala抱怨,因为
B
现在必须有一个私有的只读属性<$ c由于在inc
中引用a
,$ c> a 。将B(a:Int)
更改为B(var a:Int)
会生成不同的编译器错误:construct.scala:2:error:错误覆盖Int类型A中的变量a;
变量a需要`override'修饰符
类B(var a:Int)extends A(a){
^
发现一个错误
添加
覆盖
无助于:construct.scala:2:error:错误覆盖Int类型A中的变量a;
变量a不能覆盖可变变量
类B(覆盖变量a:Int)extends A(a){
^
发现一个错误
如何在
$B
的主构造函数中的参数中使用相同的名称作为基类的主构造函数中定义的属性A
解决方案如果从构造函数参数中删除var或val关键字,则不会生成属性。
请注意, ,非val构造函数参数在范围内并且在整个类中可访问。如果在非构造函数代码中使用一个(即在一个方法的主体中),在生成的类中将存在一个不可见的私有字段,该私有字段保存该构造函数参数,就好像你将它设置为private var或 private val构造函数参数。
附录(比迟到更好):
在此代码中,对构造函数的引用仅出现在构造函数体中:
class C1(i:Int) {
val iSquared = i * i
val iCubed = iSquared * i
val iEven = i - i%2
}
...这里的值
但是,在下面的代码中,因为构造函数参数是在方法体中引用的,而不是构造函数体的一部分 - 构造函数参数必须复制到(私有)字段生成的类(增加其内存需求的4个字节需要持有i
仅在执行构造函数时存在。Int
):class C2(i:Int){
val iSquared = i * i
val iCubed = iSquared * i
val iEven = i - i%2
def mod(d:Int)= i%d
}
In Scala, how does one define a local parameter in the primary constructor of a class that is not a data member and that, for example, serves only to initialize a data member in the base class?
For example, in the following code, how could I properly define parameter
b
in the primary constructor of classB
so that it generates only a temporary local parameter and not a data member?class A(var a: Int) class B(?b?) extends A(b)
Randall, your answers explain why the Scala compiler complains when I introduce a method
inc
that increments the propertya
, but also change the name of the parameter in the classB
constructor to match that of the parameter in the classA
constructor:class A(var a: Int) class B(a: Int) extends A(a) { def inc(value: Int) { this.a += value } }
Scala compiler output:
$ scala construct.scala construct.scala:3: error: reassignment to val def inc(value: Int) { this.a += value } ^ one error found
Scala complains because class
B
must now have a private, read-only propertya
due to the reference toa
ininc
. ChangingB(a: Int)
toB(var a: Int)
generates a different compiler error:construct.scala:2: error: error overriding variable a in class A of type Int; variable a needs `override' modifier class B(var a: Int) extends A(a) { ^ one error found
Adding
override
doesn't help, either:construct.scala:2: error: error overriding variable a in class A of type Int; variable a cannot override a mutable variable class B(override var a: Int) extends A(a) { ^ one error found
How can I use the same name in the parameter in the primary constructor of
B
as the property defined in the primary constructor of the base classA
?解决方案If you remove the "var" or "val" keyword from the constructor parameter, it does not produce a property.
Be aware, though, that non-var, non-val constructor parameters are in-scope and accessible throughout the class. If you use one in non-constructor code (i.e., in the body of a method), there will be an invisible private field in the generated class that holds that constructor parameter, just as if you made it a "private var" or "private val" constructor parameter.
Addendum (better late than never??):
In this code the references to the constructor parameter occur only in the constructor body:
class C1(i: Int) { val iSquared = i * i val iCubed = iSquared * i val iEven = i - i % 2 }
... Here the value
i
exists only during the execution of the constructor.However, in the following code, because the constructor parameter is referenced in a method body—which is not part of the constructor body—the constructor parameter must be copied to a (private) field of the generated class (increasing its memory requirement by the 4 bytes required to hold an
Int
):class C2(i: Int) { val iSquared = i * i val iCubed = iSquared * i val iEven = i - i % 2 def mod(d: Int) = i % d }
这篇关于在Scala中,如何在类的主构造函数中定义局部参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!