在Kotlin的Unit函数中累积的功能方法?

我试图强迫自己在Kotlin中使用函数式编程,并尽可能避免使用可变变量。 通常,对于一个单元返回函数的临时测试,我只是println()函数内的东西,看看它是否正常工作。 但是对于这个测试,我需要累积一个字符串,然后最终使用assertEquals(...)

和往常一样,我发现自己在封闭范围内声明了一个var ,并使用+=来积累它。 有一个更有效的方法来做到这一点,通过传递/链接一个函数,并消除可变的变种? 这里有一些简单但是说明性的代码:

 inline fun <T> Iterable<T>.forEachFrom(beg:Int, act:(T)->Unit) { var i=0; if (beg>=0) for (e in this) if (i++ >= beg) act(e) } fun main(args:Array<String>) { val l = listOf("zero", "one", "two", "three", "four") // print-to-screen test l.forEachFrom(2){print("$it-")}; println() // output: two-three-four- // accumulate-in-var test var s = "" l.forEachFrom(2){s += "$it-"}; println(s) // output: two-three-four- // Is there a purely functional way, without declaring a mutable var? // val s = l.forEachFrom(2){accumulator???("$it-")} // - OR - // val s = l.forEachFrom(2).accumulator???("$it-") // println(s) } 

一种只用kotlin-stdlib做同样的事情并保留代码的语义(即只迭代一次)的方法是将Iterable<T>转换为Sequence<T>并使用.drop(n)扩展名:

 inline fun <T> Iterable<T>.forEachFrom(beg: Int, act: (T) -> Unit) = if (beg >= 0) asSequence().drop(beg).forEach(act) else Unit 

UPD:在讨论整体问题之后,我们提出了另一种方法。

当你有一个自定义的高阶函数遍历项目,只接受回调,但不返回任何东西,你可以通过使用buildSequence { ... }包装自定义迭代逻辑到一个Sequence<T> yield(it)作为回调:

 val sequenceFromCustomFunction = buildSequence { l.forEachFrom(2) { yield(it) } } 

这允许您以功能样式处理这个序列,特别是折叠序列:

 val s = sequenceFromCustomFunction.fold("") { acc, it -> acc + it + "-" }