gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 13:14:23 25 4
gpt4 key购买 nike

我试图强制自己在Kotlin中使用函数式编程,并且尽可能避免使用可变的var。通常,对于单元返回函数的临时测试,我只需要对函数内部的内容进行println()来检查其是否正常工作。但是对于此测试,我需要累积一个字符串,然后最终使用assertEquals(...)

像往常一样,我发现自己在封闭范围内声明了var并使用+=对其进行累加。 是否存在通过传递/链接函数并消除可变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并保留代码语义(即仅迭代一次)的一种方法是convert the Iterable<T> to 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:在讨论了整个问题之后,我们提出了另一种方法。

当您具有一个自定义的高阶函数来遍历所有项并且仅接受回调但不返回任何内容时,可以通过使用 Sequence<T> 并将 buildSequence { ... }作为回调传递该自定义迭代逻辑到 yield(it)中:
val sequenceFromCustomFunction = buildSequence {
l.forEachFrom(2) { yield(it) }
}

这使您能够以功能样式使用此序列,尤其是折叠序列:
val s = sequenceFromCustomFunction.fold("") { acc, it -> acc + it + "-" }

关于functional-programming - 在Kotlin的Unit函数中积累功能的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47158107/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com