Say I'm writing an extension method
implicit class EnhancedFoo(foo: Foo) { def bar() { /* ... */ } } Should you always include extends AnyVal in the class defininition? Under what circumstances would you not want to make an implicit class a value class?
Let's look at the limitations listed for value classes and think when they may not be suitable for implicit classes:
"must have only a primary constructor with exactly one public, val parameter whose type is not a value class." So if the class you are wrapping is itself a value class, you can't use an implicit class as a wrapper, but you can do this:
// wrapped class class Meters(val value: Int) extends AnyVal { ... } // wrapper class RichMeters(val value: Int) extends AnyVal { ... } object RichMeters { implicit def wrap(m: Meter) = new RichMeter(m.value) } If your wrapper has implicit parameters as well, you can try to move them to the method declarations. I.e. instead of
implicit class RichFoo[T](foo: Foo[T])(implicit ord: Ordering[T]) { def bar(otherFoo: Foo[T]) = // something using ord } you have
implicit class RichFoo[T](foo: Foo[T]) extends AnyVal { def bar(otherFoo: Foo[T])(implicit ord: Ordering[T]) = // something using ord } "may not have specialized type parameters." You may want the wrapper to be specialized when wrapping a class which itself has specialized type parameters.
equals or hashCode method." Irrelevant, since implicit classes also shouldn't have equals/hashCode.vars or lazy vals.In addition, making your implicit class a value class could possibly change some behavior of code using reflection, but reflection shouldn't normally see implicit classes.
If your implicit class does satisfy all of those limitations, I can't think of a reason not to make it a value class.
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