2016-04-05 22 views
6

私は既存の型に新しい関数を追加しようとしています(私はIDEが自動的に制御できないタイプの関連する関数を提案することができます。例えばFuture[Option[A]])。私は、これを達成するために暗黙のクラスと暗黙的な変換の両方を調べましたが、どちらも同じ動作を提供するようです。暗黙的な変換暗黙のクラス対形質への暗黙の変換

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

と使用:

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

を私はここに1差が第1の例では、ワン作成されるかもしれないと仮定

暗黙のクラスを使用しての間で任意の有効な違いがありますクラスの代わりにクラスを使用することもできますが、暗黙的なクラスを抽象的な特性に拡張するために簡単に適応できます。例:

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

答えて

5

私が知る限り、それらはほぼ同じです。スコープ規則も両方に等しく適用されます。

私の意見では、あなたの状況に応じてimplicit classesを使用します。彼らはおそらくそれのようなもののために正確に作成されました。

私には暗黙的な変換が既に実際には2つの異なる種類のクラスを持ち、その2つの間で変換したいときに適しています。

あなたがそこに暗黙のクラスright here. のための最初の提案をチェックアウトすることができ、それは言う:

は、新しい言語構造は、別の型に拡張メソッドを提供するクラスの作成を簡素化することが提案されています。

あなたはそれがどのようにdesugarsを見ることができますimplicit classes。次:まあ、私に

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

さらに、タイプAのオブジェクトをタイプBのオブジェクトに変換する場合(ここでBは* final class * *です)、暗黙のdefが唯一のオプションです。 – Adowrath

0

好みのその問題を:

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

はにdesugarます。実際には、implicit classesは、別の型に拡張メソッドを提供するクラスの作成を容易にするようになった。 暗黙クラスはvalue classesに多くの値を追加します。