Kotlin指数和lambda表示法

时间:2018-05-30 12:21:23

标签: functional-programming kotlin

我有一个我想要遍历的JDBC结果集(称为rs),跟踪我当前正在进行的迭代。为简单起见,我们只想在一行上打印每个索引,如下面的代码段所示:

var i = 0
while ( rs.next() ) { println(i++) }

我的目标是避免使用变量,并坚持使用更具功能性的风格。

由于JDBC结果集不是迭代器,我不能简单地使用rs.withIndex { println(it) }

我已经实现了以下iwhile函数,它几乎可以满足我的需求:

tailrec fun iwhile(cond: () -> Boolean, i: Int = 0, f : (Int) -> Unit): Unit {
  if (cond ()) { f(i); iwhile(cond, i + 1, f) }
}

我唯一关心的是如何调用此函数:我必须编写

中的任何一个
iwhile({ rs.next() }) { println(it) }

iwhile({ rs.next() }) { i -> println(i) }

虽然我理想地想要写作:

iwhile ( rs.next() ) { println(i) }

请注意谓词周围没有大括号,默认名称为i而不是it

我知道这些是noob的问题,但是有没有办法写iwhile以便我可以使用最后的语法?为什么我可以写while ( rs.next() ) { println("hello") }而不是iwhile ( rs.next() ) { println("hello") }

2 个答案:

答案 0 :(得分:3)

您可以编写自己的扩展功能来提供此功能。我很快写了这个,所以它可能不会在错误处理或日志记录方面做你想做的一切,但应该接近。

fun ResultSet.nextWithIndex(fn: (idx: Int, next: ResultSet) -> Unit): Unit {
    var index = 0
    while(this.next()) {
        fn(index, this)
        index += 1
    }
}

并称之为:

val rs: ResultSet = getResultSet()
rs.nextWithIndex { idx, row ->
    row.getString("this_is_a_test")
}

发生的情况是,您的扩展函数(nextWithIndex)负责循环遍历ResultSet(这是while循环)并调用您提供的函数。因为你的函数是fn的最后一个(也是唯一的)参数(nextWithIndex),所以当你调用它时,你可以看起来就像我认为你想要的那样。

答案 1 :(得分:1)

  

为什么我可以写(rs.next()){println(“hello”)}而不是iwhile(rs.next()){println(“hello”)}?

因为Kotlin不关心让你实现这一点。 Scala确实可以获得这种语法。