0

在使用像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)
  }
}
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
}

请注意,尽管addalways 的实现看起来相同,但data每次调用的方法都是不同的重载。如果您以更多态的方式编写此代码,则add不会选择最具体的方法,并且您的IntorChar将需要装箱。

于 2016-10-03T13:37:29.010 回答