I know value class
in scala inline the operation at compiler time.
maybe like this
case class A(i: Int) extends AnyVal {
def +(that: A) = A(this.i + that.i)
}
A(1) + A(2) // After compile it equals to 1 + 2
But It seems not a big deal to me.
It might enhance performance but,
calling this.i + that.i
does not seems that much slower than i + i
Why we need value class
in scala and any use cases???
Why would you wrap a single value into an additional class?
One big use case is type safety. Let's say you have function that can multiply money, like so:
def multiply(factor: Int, amount: Int): Int = ???
The problem with this is that it would be very easy to confuse the two arguments and therefore call the function incorrectly. With values classes, you could create a Money
type and re-write the function like so:
case class Money(amount: Int) extends AnyVal
def multiply(factor: Int, amount: Money): Money = ???
Now with your special Money
type, the compiler will tell you if you try to pass arguments in the wrong order.
Were it not a value class, people may say that the added type safety is not worth the performance penalty in some cases. However with value classes, you have no runtime overhead (there are limitations though: http://docs.scala-lang.org/overviews/core/value-classes.html).
An alternative to achieve the same goal are unboxed (no runtime overhead) tagged types in scalaz: http://eed3si9n.com/learning-scalaz/Tagged+type.html
Note that for example haskell uses newtype
for the same idea: https://wiki.haskell.org/Newtype
Let's look at how Scala works with value classes (-print
option).
case class A(i: Int) extends AnyVal {
def +(that: A) = A(this.i + that.i)
}
A(1) + A(2)
is translated to:
final def +$extension($this: Int, that: Int): Int = $this.+(that)
...
A.+$extension(1, 2)
As you can see Scala avoids working with class A
and simply adds Int
to Int
returning Int
. At the same time:
case class A(i: Int) {
def +(that: A) = A(this.i + that.i)
}
A(1) + A(2)
is translated to:
def +(that: A): A = new A(this.i().+(that.i()))
...
new A(1).+(new A(2))
So to compute 1 + 2
you need to instantiate class A
three times.
Value classes are a mechanism in Scala to avoid allocating runtime objects. This is accomplished through the definition of new AnyVal subclasses.
More about value classes is here Value Classes
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With