scala类型擦除和值类
我试图绕过类型擦除,并使用值类将各种类型的值列表动态转换为json,然后使用Json4s CustomSerializer将其转换回各自的类型。但是,我无法动态提取正确的值。由于对AnyVal的引用,我在转换为Json时被迫使用value.toString,并且在从Json重新创建字段时面临问题 我在scala已经试了三个星期了,所以我还在学习诀窍。任何帮助都将不胜感激scala类型擦除和值类,scala,type-erasure,Scala,Type Erasure,我试图绕过类型擦除,并使用值类将各种类型的值列表动态转换为json,然后使用Json4s CustomSerializer将其转换回各自的类型。但是,我无法动态提取正确的值。由于对AnyVal的引用,我在转换为Json时被迫使用value.toString,并且在从Json重新创建字段时面临问题 我在scala已经试了三个星期了,所以我还在学习诀窍。任何帮助都将不胜感激 abstract class MyVal { def name: String def value: AnyVal }
abstract class MyVal {
def name: String
def value: AnyVal
}
trait Field {
def value: AnyVal
}
object Field {
def build(value: String): MyString = MyString(value)
def build(value: Int): MyInt = MyInt(value)
def build(value: Double): MyDouble = MyDouble(value)
}
case class MyString(val value: String) extends AnyVal with Field
case class MyInt(val value: Int) extends AnyVal with Field
case class MyDouble(val value: Double) extends AnyVal with Field
object MyVal {
case class StringVal(name: String, value: MyString) extends MyVal
case class IntVal(name: String, value: MyInt) extends MyVal
case class DoubleVal(name: String, value: MyDouble) extends MyVal
def build(name: String, value: String): StringVal = StringVal(name, MyString(value))
def build(name: String, value: Int): IntVal = IntVal(name, value)
def build(name: String, value: Double): DoubleVal = DoubleVal(name, value)
}
object Main {
def main(args: Array[String]) = {
var fields = Seq.empty[MyVal]
var row = Map("length" -> 1, "name" -> "test", "cost" -> 2.0)
var columns = Seq[String]("length", "name", "cost")
val fields: Seq[MyVal] = row foldLeft (Seq.empty[MyVal]) {
(previousFields: Seq[MyVal], currentField: Any) => {
columns map {
column => MyVal.build(column, Field.build(row(column)))
}
}
}
}
}
由于不明确,生成方法无法正确解析。字段的
特性定义了字段的所有可能类型:
import scala.language.existentials
import scala.language.implicitConversions
sealed trait Field extends Any {
def value: Any
}
case class MyString(val value: String) extends AnyVal with Field
case class MyInt(val value: Int) extends AnyVal with Field
case class MyDouble(val value: Double) extends AnyVal with Field
请注意下面隐含的def
s。它们允许将已知类型的值转换为字段
,而无需显式使用构建
。我们将在下面利用它
object Field {
implicit def build(value: String): MyString = MyString(value)
implicit def build(value: Int): MyInt = MyInt(value)
implicit def build(value: Double): MyDouble = MyDouble(value)
}
对于MyVal
我们不需要特定的子类-这只是复制字段的层次结构。可以说,每个值都与一个字段相关联,这捕获了相同的信息
sealed case class MyVal(name: String, value: Field)
我们仍然可以定义隐式,以便更容易地构建MyVal
s,尽管我们不需要它
object MyVal {
// notice that we use the above Field.build.. implicits here:
implicit def build(name: String, value: String): MyVal = MyVal(name, value)
implicit def build(name: String, value: Int): MyVal = MyVal(name, value)
implicit def build(name: String, value: Double): MyVal = MyVal(name, value)
}
我真的不确定您想在main
函数中表达什么。下面是一个比较简单的例子。这里的主要技巧是你不想让映射[String,Any]
。这是行不通的。一旦您丢失了映射中的类型信息,您就无法从中构建字段
s和MyVal
s而不处理无效值。您希望明确地保留值只是允许值的信息,这就是字段
的用途。通过声明Map[String,Field]
并让隐式
s为您完成枯燥的工作,您将获得以下类型安全代码:
object Main {
def main(args: Array[String]) = {
val row = Map[String,Field]("length" -> 1, "name" -> "test", "cost" -> 2.0)
val vals: Seq[MyVal] = (for((k, v) <- row.iterator) yield MyVal(k, v)).toSeq
}
}
objectmain{
def main(参数:数组[字符串])={
val行=映射[字符串,字段](“长度”->1,“名称”->“测试”,“成本”->2.0)
val val:Seq[MyVal]=(对于(k,v)