kmizuの日記

プログラミングや形式言語に関係のあることを書いたり書かなかったり。

Scala 2.10.0 M3の新機能を試してみる(2) - SIP-13 - Implicit classes

Scala 2.10.0 M3の新機能を試してみる記事第二段。今度はSIP-13 - Implicit classesです。

さて、Scalaでは従来、implicit conversionを使って、既存のクラスにメソッドを追加するPimp My Libraryと呼ばれるパターンが使われてきました。たとえば、Stringに対して、文字列を表示するdisplayメソッドを追加するためには、次のようなコードを書く必要がありました。

scala> class RichString(self: String) {
     |   def display(): Unit = println(self)
     | }
defined class RichString

scala> implicit def enrichString(self: String): RichString = new RichString(self
)
warning: there were 1 feature warnings; re-run with -feature for details
enrichString: (self: String)RichString

scala> "foo".display
foo

このPim My Libraryには、

  • implicit defによる暗黙の型変換の定義
  • 変換先のクラス(ここではRichString)に追加したいメソッドを定義する

という二つの手順を踏む必要があり、やや面倒でした。また、可読性の観点から言っても、Pimp My Libraryパターンである事がすぐにわからない事があるという欠点がありました。この欠点を改善するのが、SIP-13 - Implicit Classesです。

使い方は簡単です。追加したメソッドを持つクラスに対してimplicitキーワードを付け、そのクラスのプライマリコンストラクタに、メソッドを追加したいクラスを指定すればいいだけです。たとえば、上記のコードはimplicit classesを使って次のように書くことができます。

scala> implicit class RichString(self: String) {
     |   def display(): Unit = println(self)
     | }
defined class RichString

scala>

scala> "foo".display
foo

実に簡単ですね。従来、Pimp My Libraryパターンを使っていた箇所は、Scala 2.10以降はこのImplicit classesを使うことで簡潔に書くことができるようになります。