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

Scala data structure with type safe accessors

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

问题:给定一些输入文档,例如xml 或 json,创建一个对象 Doc,其原始内容作为变量,应用 FieldExtractors 的序列,提取一些值,即 Fields ,它们存储在 Doc 对象中,以后可以以类型安全的方式访问,例如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]
}

但我遇到了各种错误,例如:

Error:(14, 39) inferred type arguments [String] do not conform to method hasField's type parameter bounds [T <: Serializable] val result:Boolean = fieldsObject.hasField(field) ^

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

最后我会写成

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

这似乎是 Scala 有自己的 Serializable class.

的症状

String(Scala 使用它作为 java.lang.String 的同义词)实现了 Java's java.io.Serializable 而你的 Field class 已使用 Scala 的 Serializable class.

声明了泛型边界

如果将声明更改为:

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

它编译*并为我进行类型安全 get/set 检查(* 使用 Scala SDK 2.11.7,我不得不更正一些小错别字)。

请注意,Fields class 中也存在错误。我认为您打算将哈希映射声明为:

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