【发布时间】:2018-06-18 12:56:08
【问题描述】:
我的代码使用 Scala 和 Breeze 线性代数库。我有DenseVector[Double]、DenseVector[Int] 等类型的对象,其中DenseVector 是一个类似数组的容器,具有用于数值计算的专用方法。我有时需要对包含的类型使用模式匹配。类型擦除迫使我引入一个特征和“包装”案例类:
sealed trait DenseVectorRoot
case class DenseVectorReal(val data: DenseVector[Real]) extends DenseVectorRoot
case class DenseVectorMatrixReal(val data: DenseVector[DenseMatrix[Real]]) extends DenseVectorRoot
(其中Real 只是Double 的别名)。
模式匹配如下所示:
def print(data: DenseVectorRoot) =
data match {
case DenseVectorMatrixReal(_) => println("Contains real matrices")
case DenseVectorReal(_) => println("Contains real scalars")
}
我想摆脱 DenseVectorRoot 特征。我试过这个:
def print2(data: DenseVector[_ <: Any]) =
data match {
case _: DenseVector[Double] => println("Contains real matrices")
case _: DenseVector[Int] => println("Contains real scalars")
}
但是类型参数被删除了。
我应该如何使用 ClassTags 修改 print2 以便模式匹配起作用?例如,通过在以下代码中打印正确的输出:
val v0 = DenseVector(1.2, 1.5, 1.6)
val v1 = DenseVector(3, 4, 5)
val a = Array(v0, v1)
a.map(print2)
编辑
我需要管理具有不同容器的Array 的主要原因是我的代码需要管理各种类型的数据(例如,解析输入对于DenseVector[Real] 和DenseVector[Matrix[Real]] 会有所不同) .我目前的设计是将所有内容存储在Array[DenseVectorRoot] 中,然后使用.map() 等高阶函数处理数据。这个函数中的每一个都将在元素到元素的基础上进行模式匹配,以了解数据是DenseVectorReal 还是DenseVectorMatrixReal,并采取相应的行动。
这可能不是解决我的问题的最佳设计,但我在编译时不知道用户提供了哪些类型的数据。我很高兴知道任何更好的设计!
【问题讨论】:
-
为什么要在
DenseVectorReal或DenseVectorMatrixReal上下文中打印出这样的DenseVector(允许知道data的类型)? -
打印只是一个基本的例子。我实际上需要根据类型参数执行不同的数值计算。
标签: scala types pattern-matching