Reputation: 10419
In Scala I can write constructors as:
class Cons[T](head: T, tail: List[T]) {
...
}
or
class Cons[T](val head: T, val tail: List[T]) {
...
}
What's the difference?
Upvotes: 0
Views: 185
Reputation: 32335
As the others said, the difference is that val
will make the values publicly accessible with the exception of case classes that always treat the constructor parameter as a val
.
Another more subtle difference is that val
will make a field in the class, meaning that the reference to the parameter value will exist during the object lifetime.
This does not happen by default when you do not specify a val
, but still can in case that you use the constructor argument in the class body outside of the constructor body. For example, a
is used in the ctor body, so it won't be lifted into an object field below:
class A(a: Int) {
println(a)
}
In the following example, a
becomes a private field:
class A(a: Int) {
def foo = a
}
because it is necessary to have after construction and during the object lifetime to be able to call foo
.
One more place where this might implicitly happen even without referencing the parameters from the body of the class is when using specialization:
class Foo[@spec A](v: A) {
var value: A = v
}
See the bytecode:
public final A v;
flags: ACC_PUBLIC, ACC_FINAL
Signature: #12 // TA;
public A value;
flags: ACC_PUBLIC
Signature: #12 // TA;
This was tested using 2.10.1
and it is possibly a bug in the specialization implementation.
Upvotes: 2
Reputation: 125119
Specifying val
makes the property publically accessible. (This is the default behaviour for case class
parameters, without requiring val
.)
See Section 5.3 of the language spec.
Upvotes: 4