0

Scala でFastUtilsのようなフレームワークを使用する場合、フレームワーク自体が特殊化されたデータ構造を持っているため、効果的な特殊化に基づいて適切なコードをどのように生成しますか? つまり、何が特殊化されているかをプログラムでどのように把握し、適切なコードを実行するのでしょうか? では、そのような場合にパス関連の入力をどのように処理しますか。

為にobjects

class Container[@specialized T](var window: Int) {
  val data = new ObjectArrayList[T](window)
}

私はcharそれがしたいので:

class Container[@specialized T](var window: Int) {
  val data = new CharArrayList(window)
}

しかし、これは の専門化に基づいている必要がありTます。これを別の言い方をすれば、sudoコードはおそらく次のようになります

class Container[@specialized T](var window: Int) {
  val data = specialisationOf(T) match {
    case "Char" => new CharArrayList(window)
    case "Int" => new IntegerArrayList(window)
    ...
    ...
    ...
    case _ => new ObjectArrayList[T](window)
  }
}
4

1 に答える 1

1

この質問ですでに説明したように、特殊な実装を型クラスにカプセル化できます。これは、多かれ少なかれ次のコードのようになります。

import it.unimi.dsi.fastutil.ints.IntArrayList
import it.unimi.dsi.fastutil.chars.CharArrayList
import it.unimi.dsi.fastutil.objects.ObjectArrayList

class Container[@specialized(Int,Char) T](window: Int)(implicit impl: ContainerImpl[T]) {
  impl.init(window)

  def add(element: T) = impl.add(element)
  override def toString = impl.toString
}

trait ContainerImpl[@specialized(Int,Char) T] {
  def init(window: Int): Unit
  def add(element: T): Unit
  def toString: String
}

object ContainerImpl extends LowerPriorityImplicits {
  implicit def intContainer = new ContainerImplInt
  implicit def charContainer = new ContainerImplChar
}

trait LowerPriorityImplicits {
  implicit def anyContainer[T] = new ContainerImplT[T]
}

final class ContainerImplInt extends ContainerImpl[Int] {
  var data: IntArrayList = _
  def init(window: Int) = data = new IntArrayList(window)
  def add(element: Int) = data.add(element)
  override def toString = data.toString
}

final class ContainerImplChar extends ContainerImpl[Char] {
  var data: CharArrayList = _
  def init(window: Int) = data = new CharArrayList(window)
  def add(element: Char) = data.add(element)
  override def toString = data.toString
}

final class ContainerImplT[T] extends ContainerImpl[T] {
  var data: ObjectArrayList[T] = _
  def init(window: Int) = data = new ObjectArrayList(window)
  def add(element: T) = data.add(element)
  override def toString = data.toString
}

addの実装は常に同じように見えますが、呼び出されるメソッドdataは毎回異なるオーバーロードであることに注意してください。これをよりポリモーフィックな方法で記述する場合、最も具体的なadd方法は選択されず、IntorCharをボックス化する必要があります。

于 2016-10-03T13:37:29.010 に答える