言葉では説明しずらいので、とにかくまずは以下のサンプルコードみてください。Scala2.10では、implicit classでもimplicit defでも同じ
package example object A{ implicit def foo(self: Int) = new{ def a = self.toString } } object B{ implicit def foo(self: Int) = new { def b = self.toString } } object Main{ import B._ import A._ // Scala 2.10.1 では、以下は両方エラー。2.9では片方だけエラー println(1.a) println(1.b) }
Scala2.10では
- 「名前ぶつかってるよ」というエラーがでる
- importの順番によって片方がエラーになる
わけでもなく、単にどちらも無効になってコンパイルエラーとしてしかエラーが表示されないってどういうことなの・・・。例えば、上記の例では、どちらかのimplicit class Foo
をBarなどに変えれば正常にコンパイルできます。これ、普通(外部のライブラリの)implicit classやimplicit defの名前なんて関与したくないというか、基本知らなくていいわけですが、うっかり同じ名前をつけてハマるととてもわかりにくい・・・(というか実際10分くらいハマった)
そして、Scala2.9でimplicit defで同じ名前をつけた場合は「importの順番によって、後からimportしたものが優先されて有効になる」という挙動みたいなのですがががが・・・
- 2.10においては、これが仕様で、今後も変わる予定ないのか
- implicit defに関しては、Scala2.9から2.10でのこの変更は意図したものなのか、意図せず変わってしまったのか
- すでにissueが上がってるのか
- (実はこれをもっとわかりやすく表示させる)コンパイルオプションなどの何らかの対応策があるのか
など誰か知ってたら教えて下さい・・・。なにかわかったら追記とかします
追記:eed3si9nさんが ML に投稿してくれた
ambiguous implicits resolution fails silently when they are named the same