Jaime Montoya
Jaime Montoya

Reputation: 7711

Should `val` be used when defining class parameters in Scala?

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:

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

Answers (3)

Jaime Montoya
Jaime Montoya

Reputation: 7711

I found the answer in Lightbend Scala Language - Professional:

enter image description here

enter image description here

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

Tim
Tim

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

Randomness Slayer
Randomness Slayer

Reputation: 724

From the documentation you linked:

Primary constructor parameters with val and var 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 vals

point.x // 1
point.y // 2

The next paragraph explains:

Parameters without val or var 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 vals

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 classes, 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

Related Questions