2016-04-05 6 views
6

Ich versuche, neue Funktionen zu bestehenden Typen hinzuzufügen (so kann ich die IDE automatisch relevante Funktionen für Typen vorschlagen, die ich nicht kontrollieren kann, zB Future[Option[A]]). Ich habe sowohl implizite Klassen als auch implizite Konvertierungen untersucht, um dies zu erreichen, und beide scheinen dasselbe Verhalten zu bieten.Implizite Klasse vs Implizite Umwandlung in Eigenschaft

Gibt es einen effektiven Unterschied zwischen einer implizite Klasse mit:

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

Und mit einer impliziten Konvertierung:

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

Ich nehme ein Unterschied könnte sein, dass das erste Beispiel erzeugt ein ein- Aus Klasse anstelle von Merkmal, aber ich könnte leicht die implizite Klasse anpassen, um eine abstrakte Eigenschaft zu erweitern, zB:

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

Antwort

5

So weit ich weiß, sind sie ziemlich genau gleich. Die Scoping-Regeln gelten gleichermaßen für beide.

Meiner Meinung nach würde ich die implicit classes für Ihre Art von Situation verwenden. Sie wurden wahrscheinlich genau für so etwas geschaffen.

Implizite Konvertierungen sind für mich geeigneter, wenn Sie bereits zwei verschiedene Arten von Klassen haben und zwischen den beiden konvertieren möchten.

Sie können den ursprünglichen Vorschlag für implizite Klassen überprüfen right here. Es heißt es:

Ein neues Sprachkonstrukt vorgeschlagen, die Schaffung von Klassen zu vereinfachen, die auf eine andere Art Erweiterungsmethoden zur Verfügung stellen.

Sie können sogar sehen, wie es implicit classes desugars. Die folgende:

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

wird 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) 
+1

Eine zusätzliche Sache zu erwähnen ist, dass, wenn Sie implizit ein Objekt des Typs A in ein Objekt des Typs B konvertieren wollen, wobei B eine * final class' * ist, ist ein "implizites def" die einzige Option. – Adowrath

0

Nun mir seine eine Frage der Präferenz. Tatsächlich entstand die implicit classes, um die Erstellung von Klassen zu erleichtern, die Erweiterungsmethoden für einen anderen Typ bereitstellen. Implizite Klassen fügen jedoch value classes viel Wert hinzu.