请注意我正在学习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
答案 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]