作为一个例子,这是一个简单的代码。
trait DataType {
type DType
// more stuff
}
object IntType extends DataType {
type DType = Int
// more stuff
}
trait Codec {
val dtype: DataType
// more stuff
}
class DenseCodec(val dtype: DataType) extends Codec {
def get(size: Int) = new Array[dtype.DType](size)
}
val dense = new DenseCodec(IntType)
dense.get(4)
这不会编译:
cannot find class tag for element type DenseCodec.this.dtype.DType
def get(size: Int) = new Array[dtype.DType](size)
^
我知道这与Scala中的Arrays特殊有关。我可以在这里使用类似Vector的东西,它可以正常工作,但我正在研究的项目对数据处理很重要,我希望尽可能保持高效。
答案 0 :(得分:2)
这将有效
def get(size: Int)(implicit tag: ClassTag[DataType]) = new Array[DataType](size)
或使用等效的上下文绑定
def get[DType: ClassTag](size: Int) = new Array[DType](size)
您甚至可以使用模板DType
替换T
。
Array's
构造函数实际上采用类型为ClassTag
的隐式参数,因此您需要隐式或显式地提供一个参数。
编辑:另外值得注意的是,使用dtype.DType
无法使用,因为dtype
的类型DataType
没有具体的DType
,只有一个抽象的dtype.type
。有趣的val dtype: DataType
可以正常工作,因为在运行时IntType
已经是import scala.reflect.ClassTag
object Types {
trait DataType[A] {
// more stuff
}
object IntType extends DataType[Int]
object StringType extends DataType[String]
trait Codec[B] {
val dtype: DataType[B]
// more stuff
}
class DenseCodec[B](val dtype: DataType[B]) extends Codec[B] {
def get(size: Int)(implicit ct: ClassTag[B]) = new Array[B](size)
}
def main(args: Array[String]): Unit = {
val denseInt = new DenseCodec(IntType)
val arrInt = denseInt.get(4) //Array[Int]
val denseString = new DenseCodec(StringType)
val arrString = denseString.get(4) //Array[String]
}
}
。
EDIT2:如果你想传播这种类型,我担心唯一的方法就是使用类型类。
DType
这样你可以摆脱IntType
并使用类型类的类型。您没有介绍任何样板文件,因为您想要定义DType
并且可能还有更多类型。
希望这个解决你的问题:)
EDIT3:如果你想让你的trait DataType[A] {
type DType = A
// more stuff
}
继续
get
并修改def get(size: Int)(implicit ct: ClassTag[B]) = new Array[dtype.DType](size)
定义
IntType
但是这样你就会得到一个来自StringType
,vkQueueWaitIdle
等的长型签名。