具有类型安全访问器的 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]
请注意我正在学习 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]