如何 运行 和基于专业化的不同代码路径

How to Run and Different Code Paths Based on Specialisation

在将 FastUtils 这样的框架与 Scala 一起使用时,由于框架本身具有专门的数据结构,您如何根据有效的专业化生成适当的代码?即,您如何以编程方式找出正在专门化的内容并执行适当的代码?那么在这种情况下你如何处理与路径相关的类型。

对于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)
  }
}

this question 中所述,您可以将专用实现封装在类型类中。这看起来或多或少像下面的代码。

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 方法,并且您的 IntChar 将需要装箱。