Implicit class vs Implicit conversion to property

I am trying to add new functions to existing types (so that I can have the IDE automatically suggest the appropriate functions for types that I do not control, such as Future[Option[A]] ). I studied both implicit classes and implicit conversions to accomplish this, and both of them seem to offer the same behavior.

Is there any effective difference between using an implicit class:

 case class Foo(a: Int) implicit class EnrichedFoo(foo: Foo) { def beep = "boop" } Foo(1).beep // "boop" 

And using implicit conversion:

 case class Foo(a: Int) trait Enriched { def beep: String } implicit def fooToEnriched(foo: Foo) = new Enriched { def beep = "boop" } Foo(1).beep // "boop" 

I believe that one difference here may be that the first example creates a one-time class instead of the attribute, but I could easily adapt the implicit class to extend the abstract attribute, for example:

 case class Foo(a: Int) trait Enriched { def beep: String } implicit class EnrichedFoo(foo: Foo) extends Enriched { def beep = "boop" } Foo(1).beep // "boop" 
+7
source share
3 answers

As far as I know, they are almost the same. The table of contents rules also apply equally to both.

In my opinion, I would use implicit classes for your situation. They were probably created just for something like that.

Implicit conversions, for me, are more appropriate when you already have two different classes and you want to convert between them.

You can check the original sentence for implicit classes right here. It says:

A new language construct is proposed to simplify the creation of classes that provide extension methods for another type.

You can even see how these are desugars implicit classes . Following:

 implicit class RichInt(n: Int) extends Ordered[Int] { def min(m: Int): Int = if (n <= m) n else m ... } 

will desugar in:

 class RichInt(n: Int) extends Ordered[Int] { def min(m: Int): Int = if (n <= m) n else m ... } implicit final def RichInt(n: Int): RichInt = new RichInt(n) 
+7
source

Well to me this is a matter of preference. In fact, implicit classes have appeared to facilitate the creation of classes that provide extension methods to another type. Implicit classes add a lot of value to value classes , though.

+1
source

To add an answer to Luke Jacobowitz: implicit classes are mostly extensions. An implicit conversion is used to tell the compiler that it can be considered as something with an extension.

It sounds almost the same. Two things of interest from an implicit conversion have some difference:

First: you may need to activate a language feature to turn off alerts when using implicit conversion.

Second: I would not call it a "conversion" of the type:

Implicit conversions are applied in two situations: if the expression e is of type S, and S does not match the expressions of the expected type of T. [Or:] In the choice of em with e of type S, if the selector m does not denote C.

 case class Foo(a: Int) trait Enriched { def beep: String } implicit def fooToEnriched(foo: Foo) = new Enriched { def beep = "boop" } Foo(1) match { case _:Enriched => println("is an Enriched") case _:Foo => println("no, was a Foo") } // no, was a Foo 

but it can be seen as enriched ...

 val enriched: Enriched = Foo(2) enriched match { case _:Enriched => println("is an Enriched") case _:Foo => println("no, was a Foo") } // is an Enriched // plus unreachable code warning: case _:Foo => println("no, was a Foo") 
0
source

All Articles