Better to use vals or object when providing class instances in Scala

A type type template in Scala includes a character definition, for example:

trait Show[T] { def show(obj: T): String } 

Then you can define instances of this type of class as such:

 object Show { implicit val string = new Show[String] { def show(obj: String): String = obj } implicit object BooleanShow extends Show[Boolean] { def show(obj: Boolean): String = obj.toString } } 

The advantage of defining these instances for base types in a companion object is that they automatically fall into scope whenever it comes to class type (approximately).

Functionally, it would seem that the definition of an instance as an implicit val or an implicit object does not change much.

Is there any difference? Is one way better than another?

+6
source share
3 answers

In fact, there are more type names between val and object .

You know, an object in Scala is something like a singleton in Java.
You might have thought that both string and BooleanShow are in an object not a class , so they make no difference, but that is not the case.

They are val and object no matter what.

Try this in the Scala REPL.

 trait Show[T] { def show(obj: T): String } object Show { println("!! Show created") implicit val string = new Show[String] { println("!! string created") def show(obj: String): String = obj } implicit object BooleanShow extends Show[Boolean] { println("!!BooleanShow created") def show(obj: Boolean): String = obj.toString } } 

If only the definition is executed, then no println is executed after Show is a single. It has not been created yet.

Then do a Show in the Scala REPL.

 scala> Show !! Show created !! string created res0: Show.type = Show$@35afff3b 

You see, println in Show and Show.string were called, but in Show.BooleanShow not.

You can run Show.BooleanShow further in the Scala REPL.

 scala> Show.BooleanShow !!BooleanShow created res1: Show.BooleanShow.type = Show$BooleanShow$@18e419c5 

Show.BooleanShow was finally initialized. This is a singleton, so he is lazy .

Basically, your question is the same as val and the object inside the Scala class , except that your val and object defined in object , but the related question tries to find the differences between val and object defined in the class , and the method in val uses reflection ( but yours uses redefinition, therefore reflection is not involved). implicit basically does not affect what they are.

I think you already know the difference between class and object . Further information can be found in the related question.

+1
source

Since they say always use explicit types for implicits, prefer val over the object.

Compare Why can't Scala find my typeclass instance implicitly in the companion object when the class type is not in the selected source file? where he is the difference.

Make it lazy if necessary.

Development:

 scala> trait T defined trait T scala> object X { implicitly[T] ; object O extends T } <console>:8: error: could not find implicit value for parameter e: T object X { implicitly[T] ; object O extends T } ^ scala> object X { implicitly[T] ; implicit object O extends T } <console>:8: error: could not find implicit value for parameter e: T object X { implicitly[T] ; implicit object O extends T } ^ scala> object X { implicitly[O.type] ; implicit object O extends T } defined object X scala> object X { implicitly[T] ; implicit object O extends T ; implicit def y = O } <console>:8: error: could not find implicit value for parameter e: T object X { implicitly[T] ; implicit object O extends T ; implicit def y = O } ^ scala> object X { implicitly[T] ; implicit object O extends T ; implicit def y: T = O } defined object X 

The deduced type O is the singleton type O.type .

+1
source

With val x = new X { } you create an anonymous subclass of X , while with object x extends X you create the β€œright” subclass. I think object overhead is minimal, and as @applicius points out, it has its own name. Therefore, I suggest going to object in this case.

0
source

Source: https://habr.com/ru/post/974400/


All Articles