2013-02-06 38 views
4

我正在尝试使用新的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 defimport 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 
} 
+1

您之前忘记了“val”(row:ResultSet):D – twillouer

+0

之前,您将函数resultSet转换为Stream。现在,要做同样的事情,你必须打电话给Stream。隐式类不是隐式函数。 Personnaly,我更喜欢隐式类的第二种方法和toStream的“强制”调用。如果你真的想要“映射”,你必须在你的隐式类中定义一个“映射”函数,它将成为流的包装器 – twillouer

+0

实际上,我认为使用'toStream'方法比隐式隐式更好。 –

回答

4

我在这里看不到一个理由使用隐含的类。坚持你的第一个版本。隐式类主要用于将方法添加到现有类型(所谓的“丰富我的库”模式)中(如“简明”)。 它只是包装类的语法糖,并且隐式转换为此类。

但在这里你只是从一个转换(隐含的)预先存在到另一种预先存在类型。根本不需要定义一个新类(更不用说一个隐式类)。

在你的情况,你可以使它工作通过使ResultSetStream延长Stream和实施作为代理toStream使用隐式类。但是,这真的很麻烦。