我将在Scala中创建JDBC ResultSet的包装器 .
此包装器旨在成为函数 ResultSet => ParticularType
.
问题是我无法找到制作MultiMaps的通用解决方案 .
这是我获取集合的方式:
abstract class CollectionCreator[C] extends (ResultSet => C) {
def apply(rs: ResultSet): C = {
do { append(rs) } while (rs.next)
returnCollection()
}
def append(rs: ResultSet)
def returnCollection(): C
}
接下来是 Map 创建 . 它是集合创建的一个实现,它不是抽象的,因为map非抽象(在我的实现中总是用HashMap进行反馈) .
在我看来,它应该是这样的:
class MapCreator[K,IV](keyCreator: ResultSet => K, valueCreator: ResultSet => IV)
extends CollectionCreator[Map[K, Place for V]] {
type V = IV
val intermediateMap = new HashMap[K, V]
override def append(rs: ResultSet) {
appendToMap(keyCreator(rs), valueCreator(rs))
}
def appendToMap(key: K, value: IV) {
intermediateMap(key) = value
}
override def returnCollection(): Map[K,V] = intermediateMap.toMap
}
如果它有效,我会用这种方式编写ListMultiMap:
class ListMultiMapCreator[K,IV](keyCreator: ResultSet => K, valueCreator: ResultSet => IV)
extends MapCreator[K, Place for V](keyCreator, valueCreator) {
override type V = List[IV]
override def appendToMap(key: K, value: IV) {
intermediateMap(key) = intermediateMap.get(key) match {
case Some(values) => values.::(value)
case None => List(value)
}
}
}
问题是我不能在 Place for V
使用 V
因为它当时没有被声明 .
我觉得抽象类型是很好的解决方案,但不知道如何正确对待它们 .
创建这样的集合的正确方法是什么?
我也不确定是否可以覆盖已在类层次结构中定义得更高的抽象类型 .
1 回答
在您的定义中,
MapCreator
实际上将IV
和V
限制为相同的类型 . 按 Contract ,Map[K,V]
中返回的V
必须与valueCreator
返回的类型相同 . 例如,如果我打电话:我希望得到
Map[String,String]
. 如果扩展MapCreator
,则无法更改该关系 . 如果你想要一个Map[String,List[String]]
,你需要提供(ResultSet) => List[String]
类型(ResultSet) => List[String]
.考虑到这一点,您可以像这样更改定义和实现:
我觉得因为
CollectionCreator
使用了一个类型参数,所以使用抽象类型会很麻烦 . 总的来说,似乎有很多锅炉板 . 我会利用更多的scala库:同样在你的_1280987中如果结果集为空怎么办?