我正在尝试使用新的Scala 2.10 implicit class
机制将java.sql.ResultSet
转换为scala.collection.immutable.Stream
。在斯卡拉2.9我用下面的代码,它的工作原理:使用Scala 2.10隐式类转换为“内置”标准库类
/**
* Implicitly convert a ResultSet to a Stream[ResultSet]. The Stream can then be
* traversed using the usual methods map, filter, etc.
*
* @param resultSet the Result to convert
* @return a Stream wrapped around the ResultSet
*/
implicit def resultSet2Stream(resultSet: ResultSet): Stream[ResultSet] = {
if (resultSet.next) Stream.cons(resultSet, resultSet2Stream(resultSet))
else {
resultSet.close()
Stream.empty
}
}
然后我就可以这样使用它:
val resultSet = statement.executeQuery("SELECT * FROM foo")
resultSet.map {
row => /* ... */
}
的implicit class
,我想出了这个样子的:
/**
* Implicitly convert a ResultSet to a Stream[ResultSet]. The Stream can then be
* traversed using the usual map, filter, etc.
*/
implicit class ResultSetStream(val row: ResultSet)
extends AnyVal {
def toStream: Stream[ResultSet] = {
if (row.next) Stream.cons(row, row.toStream)
else {
row.close()
Stream.empty
}
}
}
但是,现在我必须在ResultSet
上拨打toStream
,哪种类型打败了“隐式”部分:
val resultSet = statement.executeQuery("SELECT * FROM foo")
resultSet.toStream.map {
row => /* ... */
}
我在做什么错?
我还应该使用implicit def
和import scala.language.implicitConversions
来避免“功能”警告吗?
UPDATE
这里是一个替代的解决方案是,ResultSet
转换为scala.collection.Iterator
(仅斯卡拉2.10+):
/*
* Treat a java.sql.ResultSet as an Iterator, allowing operations like filter,
* map, etc.
*
* Sample usage:
* val resultSet = statement.executeQuery("...")
* resultSet.map {
* resultSet =>
* // ...
* }
*/
implicit class ResultSetIterator(resultSet: ResultSet)
extends Iterator[ResultSet] {
def hasNext: Boolean = resultSet.next()
def next() = resultSet
}
您之前忘记了“val”(row:ResultSet):D – twillouer
之前,您将函数resultSet转换为Stream。现在,要做同样的事情,你必须打电话给Stream。隐式类不是隐式函数。 Personnaly,我更喜欢隐式类的第二种方法和toStream的“强制”调用。如果你真的想要“映射”,你必须在你的隐式类中定义一个“映射”函数,它将成为流的包装器 – twillouer
实际上,我认为使用'toStream'方法比隐式隐式更好。 –