0

Reading the Value Classes and Universal Traits post, I looked at the RichInt example.

But, I changed the self field to leave off the val.

scala> class RichInt(self: Int) extends AnyVal {
     |  def toHexString: String = java.lang.Integer.toHexString(self)
     | }
<console>:7: error: value class parameter must be a val and not be private[this]
       class RichInt(self: Int) extends AnyVal {
                     ^

I got a compile-time error. It appears that omitting the val results in the field have accessibility of private[this].

What's the significance of keeping versus excluding val? I'm not sure what must be a val actually means.

Kevin Meredith
  • 41,036
  • 63
  • 209
  • 384

1 Answers1

3

Perhaps the wording must be a val is a bit off. More specifically, the value class parameter must be a public val, as stated in that very article.

A value class …

… must have only a primary constructor with exactly one public, val parameter whose type is not a value class.

Declaring class RichInt(val self: Int) extends AnyVal, means that a public accessor for self will be created by the compiler for class RichInt. If you remove the val declaration from within the constructor, then self will be private within instances of the class (and only accessible to this instance).

Community
  • 1
  • 1
Michael Zajac
  • 55,144
  • 7
  • 113
  • 138
  • It also says *(From Scala 2.11.0, the parameter may be non-public.)*, but that doesn't seem to work in 2.11. – Michael Zajac Apr 19 '15 at 15:59
  • `class RichInt(private val self: Int) extends AnyVal {}` works for me using 2.11.6 – Marth Apr 19 '15 at 16:10
  • Ah, I guess it's that it just can't be `private[this]`. – Michael Zajac Apr 19 '15 at 16:14
  • @m-z, I'm confused by `then self will be private within instances of the class (and only accessible to this instance).` Instantiating a case class, `Foo(x: String)`, allows the `x` field to be "gotten" via a public accessor. – Kevin Meredith Apr 19 '15 at 18:37
  • 1
    @KevinMeredith But case classes are special, they automatically add public accessors for the constructor fields, unless otherwise specified. Regular classes do not do this, they are automatically `private[this]`. The `RichInt` example is not a case class, and therefore no automatic public accessor. – Michael Zajac Apr 20 '15 at 02:10