具有类型安全访问器的Scala数据结构

时间:2015-11-10 21:35:43

标签: scala generics collections types type-safety

请注意我正在学习Scala,所以我建议的可能不是实现这一目标的最佳(实际)方式,因此我将描述我首先要解决的问题,然后是我当前的实现!

问题:给定一些输入文档,例如xml或json,创建一个对象Doc,其原始内容为变量,应用FieldExtractors序列,提取一些值,即Fields,存储在{Doc 1}}对象,可以在以后以类型安全的方式访问,例如val username: String = doc.getField(UsernameField)

N.B 一切都必须是可序列化的,所以它可以通过特定的框架通过网络传递

所以,我目前的尝试:

abstract class Field[+T <: Serializable](val name: String, val valueType: Class[T])

trait Fields {
  var fields: mutable.HashMap[Class[Field[Serializable]], Field[Serializable]] = mutable.HashMap()
  def hasField[T <: Serializable](field: Field[T]): Boolean = false
  def getField[T <: Serializable](field: Field[T]): T = fields.get(field).asInstanceOf(T)
  def setField[T <: Serializable](field: Field[T], value: T): Unit = fields.put(field, value)
}

class Doc(val rawData: String) with Fields

abstract class FieldExtractor[+TYPE <: Serializable](val field: Field[TYPE])  {
  def extractField(input: Doc): Option[TYPE]
}

但我得到各种各样的错误,例如:

  

错误:(14,39)推断类型参数[String]不符合方法hasField的类型参数bounds [T&lt;:Serializable]       val result:Boolean = fieldsObject.hasField(field)                                         ^

我想知道是否应该使用Value类型?或https://github.com/mikaelv/strucs项目(看起来相当年轻)?或者是否有更好的方法?

最终我写了类似

的内容
extractors.foldLeft(doc)((doc, extractor) => doc.setField(field, extractor.extractField(doc); doc

1 个答案:

答案 0 :(得分:3)

这似乎是Scala有自己的Serializable类的症状。

String(Scala用作java.lang.String的同义词)实现 Java java.io.Serializable,而您的Field类已声明使用 Scala&#39> Serializable类的通用边界。

如果您将声明更改为:

abstract class Field[+T <: java.io.Serializable](val name: String, val valueType: Class[T])

它编译*并为我正确执行类型安全get / set检查(*使用Scala SDK 2.11.7,我必须纠正一些小错字)。

注意,Fields类中也存在错误。我认为你的意思是将哈希映射声明为:

fields: mutable.HashMap[Field[Serializable], Serializable]