2016-04-05 12 views
6

Próbuję dodać nowe funkcje do istniejących typów (więc mogę mieć auto IDE zasugerować odpowiednie funkcje dla typów nie mam kontroli nad np Future[Option[A]]). Zbadałem zarówno niejawne klasy, jak i niejawne konwersje, aby to osiągnąć i oba wydają się oferować to samo zachowanie.niejawny klasa vs niejawna konwersja do trait

Czy istnieje skuteczny różnica między używaniem niejawny Klasa:

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

i korzystania niejawna konwersja:

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

Przypuszczam jedna różnica tutaj może być tak, że pierwszy przykład tworzy jedno- poza klasą zamiast cechą, ale mogłem z łatwością dostosować ukrytą klasę do rozszerzenia abstrakcyjnej cechy, np .:

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

Odpowiedz

5

O ile mi wiadomo, są one dokładnie takie same. Zasady ustalania zakresu odnoszą się również do obu.

Moim zdaniem, to bym użyć implicit classes do takiej sytuacji. Prawdopodobnie zostały stworzone właśnie z myślą o czymś takim.

niejawne konwersje, do mnie, są bardziej odpowiednie, kiedy już rzeczywiście mają dwa różne rodzaje zajęć i chcą konwertować między nimi.

Możesz sprawdzić wstępną propozycję ukrytych klas right here. tam mówi:

nowa konstrukcja język proponuje uproszczenie tworzenia klas, które zapewniają metody rozszerzenie do innego typu.

Można nawet zobaczyć, jak wygasza implicit classes. Poniższy:

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

będzie desugar do:

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

Jedna dodatkowa rzeczą wspomnieć, że kiedy chcesz niejawnie przekonwertować obiekt typu A do obiektu typu B, gdzie B jest ostateczna class' * '*' niejawny def' jest to jedyna opcja. – Adowrath

0

Dobrze mi swoją kwestia preferencji. W rzeczywistości powstał implicit classes, aby ułatwić tworzenie klas, które udostępniają metody rozszerzania do innego typu. Jednak niejawne klasy dodają wiele wartości do value classes.

Powiązane problemy