[英]Make code be more in functional-style
這是Java-Scala代碼:
class MyDbManager extends SQLiteOpenHelper ....
val cursor = new MyDbManager().getReadableDatabase.query(....)
val result = new ArrayList[MyItem] //???
//?????????
if (cursor.moveToFirst()) {
do {
result + parse(cursor)
} while (cursor.moveToNext())
}
//?????????
cursor.close()
result
我想做的是不能使用任何可變的集合和帶有可變變量的不可變集合。 我想做這樣的事情:
val result = if (cursor.moveToFirst()) {
do { parse(cursor) } while (cursor.moveToNext())
}
您有個主意:不使用任何冗余變量,尤其是可變變量。 當然,上面的代碼不會編譯。
如果可能的話我該怎么辦? 我想在不涉及任何第三方庫的情況下做到這一點,並且要盡可能地簡單。
更新 :建議“為”。 因為在我的情況下,“ for”轉換為“ map”和“ filter”,所以我想知道為什么這行不通:
if.(cursor.moveToFirst()) cursor.filter(_.moveToNext()).map { x => parse(x) }
該代碼基於java.sql.ResultSet
,但是該模式也應適用於您的情況。
您可以這樣定義一個類:
class Cursor[T](rs: ResultSet)(f: Row => T) {
def foreach(g: T => Unit) {
val row = new Row(rs)
while (rs.next()) {
g(f(row))
}
}
}
它有兩個參數:
f
為每一行生成一個實例。 因此,在迭代期間,將基於當前行構造實例。 Cursor
類提供了一個foreach
方法。 因此可以用於“理解”中:
val cursor = Cursor(rs) {
row =>
Person(row.getString(1), row.getString(2))
}
for {
person <- cursor
} {
println(person)
}
為了能夠對函數f
使用{ ... }
語法,需要一個伴隨對象:
object Cursor {
def apply[T](rs: ResultSet)(f: Row => T) = {
new Cursor(rs)(f)
}
}
使用包裝器類Row
表示結果集的一行,因為基礎結果集的某些方法對函數不可見(例如next()
)。
class Row(rs: ResultSet) {
def getString(n: Int) = rs.getString(n)
def getInt(n: Int) = rs.getInt(n)
// ... more getters for other types
}
class CursorWithIterator[T](rs: ResultSet)(f: Row => T) extends Iterator[T] {
private val row = new Row(rs)
override def hasNext = rs.next()
override def next() = f(row)
}
您也可以在中使用Iterator
進行“理解”。 它使您可以訪問完整的集合API,例如map
等。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.