2009-09-10 7 views
23

私は透明implicit変換は本当にこのような良いアイデアであり、明示的、ええと、実際にはより暗黙を使用する方がよいかもしれませんかどうかかどうかを疑問に思ってきました。例えば、私はパラメータとしてDateを受け入れ、私はDateStringをオン暗黙の変換を持っている方法があるとします。Scalaの暗黙の使用方法の選択肢

implicit def str2date(s: String) : Date = new SimpleDateFormat("yyyyMMdd").parse(s) 

private def foo(d: Date) 

その後、明らかに私は透明implicit変換でこれを呼び出すことができます。

foo("20090910") 

文字列をより明示的な日付に変換していることを確認する方がよいでしょうか?

class DateString(val s: String) { 
    def toDate : Date = new SimpleDateFormat("yyyyMMdd").parse(s) 
} 

implicit def str2datestr(s: String) : DateString = new DateString(s) 

それでは使用量は、より次のようになります。

foo("20090910".toDate) 

これの利点は、それが何が起こっているかで、後に明確であるということである - 私は透明implicitで今数回を見破られてきました私が知るべき変換(OptionIterableの人は誰ですか?)と、この使用法はまだimplicitの力を利用することができます。

答えて

43

暗黙の変換を行う "明示的な"方法は、少なくともこの例では、完全に透明なものよりも読みやすさの面ではるかに優れていると思います。あなたは常にとタイプBのオブジェクトが必要なときにはいつでも使用することができるというようなタイプAのオブジェクトを表示することができたときにBを入力するタイプAから完全に透過的にimplicit Sを使用して、私の意見では

は、OKです。たとえば、 StringRandomAccessSeq[Char]に暗黙的に変換すると、常に意味があります。 Stringは、常に概念的には文字列として表示されます(Cでは、文字列は 、文字列はたとえばです)。 x.foreach(println)の呼び出しは、 のすべての意味があります。 Stringです。タイプ Aの目的は、 時々タイプ Bの対象として使用することができる場合に一方

は、より明示的な変換が使用されるべきです。あなたの例では、foo("bar")の呼び出しは意味をなさないし、エラーをスローします。 Scalaにチェック例外がないため、foo(s.toDate)の呼び出しは、例外がスローされる可能性があることを明確に示します(sは有効な日付ではない可能性があります)。また、foo("bar".toDate)は明らかに間違っていますが、foo("bar")が間違っている理由を調べるためにドキュメントを参照する必要があります。 Scalaの標準ライブラリのこの例はRichStringラッパー(String sはInt Sとして見ることができるではなく、すべての時間)のtoInt方法を介して、IntString Sからの変換です。

13

XからYへの暗黙的な変換(上記のStringからDateへの変換のように)は、基本的に、Xを最初に書くことを完全に制御していれば、X実装するか、Yのサブクラスである

XがYを実装することが理にかなっている場合は、変換を追加します。そうでなければ、それは適切ではないかもしれません。たとえば、StringがRandomAccessSeq [Char]を実装するのは理にかなっていますが、StringがDateを実装するのは意味がありません(StringDateを実装するStringは問題ありません)。

(私はちょっと遅く、Flaviuは優れた答えを持っていますが、私は暗黙のことについてどのように考えているのかコメントしました)

関連する問題