3

LongArrayWritableというタイプがあり、これはLongの配列のボックス化された表現であるとしましょう。これらのタイプ間で変換する暗黙の定義があります。

implicit def boxLongArray(array: Array[Long]) : LongArrayWritable { /*elided*/}
implicit def unboxLongArray(array: LongArrayWritable) : Array[Long] { /*elided*/}

今、私はjava.lang.Iterableとscala.collection.List[X]の間でそれらの一般的な形式で変換する暗黙的なものも持っています:

implicit def iterator2list[X](it : java.lang.Iterable[X]) : List[X] { /* elided */ }
implicit def list2iterator[X](list : List[X]) : java.lang.Iterable[X] { /* elided */ }

これらの定義を使用して、scalaコンパイラーはjava.lang.Iterable[LongArrayWritable]とList[Array [Long]](と同等iterator2list(iterator).map(unboxLongArray(_)))の間の暗黙的な変換を推測できますか、またはこれは暗黙的な機能を超えているため、独自の(明示的?)暗黙的定義?

ありがとう、

ティム

4

1 に答える 1

7

この質問をカバーする投稿があります:Scalaで暗黙を連鎖させるにはどうすればよいですか?。基本的に、への変換にはビューをバインドする必要がありますLongArrayWritable。つまり、にdef変換LongArrayWritableする暗黙の引数は、暗黙の引数(ビューバウンドと呼ばれる)を受け取るため、これに対する引数defは直接ではなく、 :Arrayに変換できる何らかの型になります。Array

object LongArrayWritable {
  implicit def fromArraySource[A <% Array[Long]](a: A): LongArrayWritable = apply(a)
}
case class LongArrayWritable(a: Array[Long])

def test(a: LongArrayWritable): Unit = println("OK")

現在、これはアレイで機能します。

test(Array( 1L, 2L, 3L))

ただし、はでArrayはなく、スコープ内のからへIterableのデフォルトの変換がないため、次の1つを追加する必要があります。 IterableArray

implicit def iterable2Array[A: ClassManifest](i: Iterable[A]): Array[A] = i.toArray

その後、それは動作します:

test(List(1L, 2L, 3L))

ビューバウンドA <% Array[Long]は、タイプの暗黙の引数のショートカットであるため、次のA => Array[Long]ように記述することもできます。

implicit def fromArraySource[A](a: A)(implicit view: A => Array[Long]) ...
于 2011-03-30T13:48:52.373 に答える