Reputation: 7711
In the Scala documentation at https://docs.scala-lang.org/tour/classes.html, the following example shows a minimal class definition that includes parameters:
class Point(var x: Int, var y: Int) {
...
}
Both of the following code snippets work correctly for me:
class Train(number: Int)
class Train(val number: Int)
What would be the benefit of using val
in snippet 2? From what I understand, by default val
is implicit. Would code readability by being explicit to say that number
is a val
and not a var
be the only benefit? Thank you.
Upvotes: 2
Views: 702
Reputation: 7711
I found the answer in Lightbend Scala Language - Professional:
I confirmed it from the REPL:
scala> class Hello(message: String)
class Hello
scala> val hello = new Hello("Hello, world!")
val hello: Hello = Hello@2a454afb
scala> hello.message
^
error: value message is not a member of Hello
scala> class Hello(val message: String)
class Hello
scala> val hello = new Hello("Hello, world!")
val hello: Hello = Hello@639e35dc
scala> hello.message
val res7: String = Hello, world!
Upvotes: 1
Reputation: 27421
In Snippet 1, number
is a construction parameter and is not a member of the class. It can only be used inside the constructor (the body of the class
).
In Snippet 2, number
is a public read-only member of the class. It can be used by any code that has an instance of the class.
From what I understand, by default
val
is implicit.
This is not true for class
parameters but is true for case class
parameters, which can cause confusion when learning Scala.
Upvotes: 2
Reputation: 724
From the documentation you linked:
Primary constructor parameters with
val
andvar
are public.
E.g. (as in the example):
class Point(val x: Int, val y: Int)
val point = new Point(1, 2)
point.x = 3 // <-- does not compile (because vals are immutable)
In this definition you can access x
and y
, as they are public val
s
point.x // 1
point.y // 2
The next paragraph explains:
Parameters without
val
orvar
are private values, visible only within the class.
E.g. (as in the example):
class Point(x: Int, y: Int)
val point = new Point(1, 2)
point.x // <-- does not compile
In this definition, x
and y
are private val
s
Thus your snippet 1 has a private val
called number
And your snippet 2 has a public val
called number
(Just to note) A small caveat to this is case class
es, where all arguments of the constructor are public, regardless of the val
or var
keyword. If omitted, the variable/value will be public.
Upvotes: 4