l'essentiel est invisible pour les yeux

Wednesday, March 11, 2009

[Scala Tips] Java型からScalaのラッパー型への明示的変換を仲介してくれるライブラリ

Scalaでは、Javaの型の多くをラップしたクラスにて再定義している。

byte型 -> scala.Byte
short型 -> scala.Short
int型 -> scala.Int
など。

そのため、ScalaからJavaのライブラリを利用していると、ライブラリのAPIの返り値がJavaの型で、Scalaのラッパークラスではないので変換が必要な事がよくある。例えば、java.util.List型は、ScalaのSeq[A]を継承していないので、enumerableではない。

このため、Scalaの標準ライブラリ中にいくつかの明示的な変換規則を定義してある。例えば、java.util.List[T]からList型への変換などは、scala.collection.jcl.Conversion.convertListを読みこむだけで、後はScalaの言語仕様の明示的な型変換機構により自動的に変換してくれる。


var primNumberList = new java.util.ArrayList[Int](3)
primNumberList.add(1)
primNumberList.add(3)
primNumberList.add(5)

// ScalaのSeq[A]を実装していないのでイテレーターとして扱えない
primNumberList.foreach { println(_) } // ERROR: エラー

// implicit conversionの読みこみ
import scala.collection.jcl.Conversions.convertList
primNumberList.foreach { println(_) }
1
3
5


java.util.ListからList型への変換以外にも、java.util.MapからMap, java.util.SetからSetなど、多数の明示的変換が定義されているので、必要に応じて読みこむと使用できる。

package scala.collection.jcl

object Conversions {
implicit def convertSet[T](set : java.util.Set[T]) = Set(set)
implicit def convertList[T](set : java.util.List[T]) = Buffer(set)
implicit def convertSortedSet[T](set : java.util.SortedSet[T]) = SortedSet(set)
implicit def convertMap[T,E](set : java.util.Map[T,E]) = Map(set)
implicit def convertSortedMap[T,E](set : java.util.SortedMap[T,E]) = SortedMap(set)

implicit def unconvertSet[T](set : SetWrapper[T]) = set.underlying
implicit def unconvertCollection[T](set : CollectionWrapper[T]) = set.underlying
implicit def unconvertList[T](set : BufferWrapper[T]) = set.underlying
implicit def unconvertSortedSet[T](set : SortedSetWrapper[T]) = set.underlying
implicit def unconvertMap[T,E](set : MapWrapper[T,E]) = set.underlying
implicit def unconvertSortedMap[T,E](set : SortedMapWrapper[T,E]) = set.underlying

}