采用以下单行,可以表示为对集合或序列的一系列操作:
val nums = (10 downTo 1)
// .asSequence() if we want this to be a sequence
.filter { it % 2 == 0 }
.map { it * it }
.sorted()
// .asList() if declaring it a sequence
println(nums) // [4, 16, 36, 64, 100]
假设我想在每一步看到元素,它们将是(来自演绎):
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
[10, 8, 6, 4, 2]
[100, 64, 36, 16, 4]
[4, 16, 36, 64, 100]
不幸的是,没有好的方法可以使用调试器对其进行调试,也可以记录这些值以供以后检查。使用良好的函数式编程结构,整个方法可以像这样重写为单个语句,但似乎没有好的方法来检查中间状态,甚至是计数(10, 5, 5, 5
这里)。
调试这些的最佳方法是什么?
答案 0 :(得分:8)
您可以使用
记录中间值(列表)fun <T> T.log(): T { println(this); this }
//USAGE:
val nums = (10 downTo 1)
.filter { it % 2 == 0 }.log()
.map { it * it }.log()
.sorted().log()
这将按照您的需要工作,因为在您的示例中,您使用集合而不是序列。对于懒惰的Sequence
,您需要:
// coming in 1.1
public fun <T> Sequence<T>.onEach(action: (T) -> Unit): Sequence<T> {
return map {
action(it)
it
}
}
fun <T> Sequence<T>.log() = onEach {print(it)}
//USAGE:
val nums = (10 downTo 1).asSequance()
.filter { it % 2 == 0 }
.map { it * it }.log()
.sorted()
.toList()
答案 1 :(得分:7)
在最新的Intellij Idea中添加断点时,您可以选择将其设置为不检查整个表达式,而只检查Lambda体。
然后在调试本身中,您可以看到Lambda内部发生了什么。
但这不是唯一的方法。您也可以使用Run to cursor (Alt + F9)。
答案 2 :(得分:2)
我认为目前正确答案是您需要Kotlin Sequence Debugger插件,它允许您使用IntelliJ可爱的Java流调试器和Kotlin序列。
请注意(除非我做错了)它似乎不适用于集合,因此您必须将集合转换为序列才能进行调试。使用Iterable.asSequence很容易,并且需要付出很小的代价 - 一旦完成调试,您总是可以恢复该更改。
答案 3 :(得分:0)
您可以使用 also
内联函数记录日志,在任何序列阶段打印为 explained by Andrey Breslav at Google I/O '18
(1..10)
.filter { it % 2 == 0 }
.also { e -> println(e) /* do your debug or print here */ }
.map { it * 2 }
.toList()