0

带列表的代码:

println(listOf(1, 2, 3).windowed(1))
println(listOf(1, 2, 3).windowed(1) { it })
println(listOf(1, 2, 3).windowed(1) { it.toList() })

结果:

[[1], [2], [3]]
[[3], [3], [3]]  //why is there 3 everywhere?
[[1], [2], [3]]

带序列的代码:

println(sequenceOf(1, 2, 3).windowed(1).toList())
println(sequenceOf(1, 2, 3).windowed(1) { it }.toList())
println(sequenceOf(1, 2, 3).windowed(1) { it.toList() }.toList())

结果:

[[1], [2], [3]]
[[], [], []]     //why?!
[[1], [2], [3]]

请解释

4

1 回答 1

3

它在函数的文档中:

请注意,传递给转换函数的列表是短暂的,并且仅在该函数内部有效。您不应该存储它或让它以某种方式逃逸,除非您制作了它的快照。

作为一个实现细节,这个高阶函数为窗口的每个元素重用相同的列表实例,并在两者之间清除/重新填充它。这避免了必须分配许多列表。

通过将其作为转换函数的返回值传递,您允许列表实例转义,因为它们警告您不要这样做。

在您的第三个示例中,您使用 返回列表的副本toList(),因此它可以正常工作。

当您对序列执行此操作时,结果会有所不同,因为该函数在内部以不同方式处理列表和其他可迭代类型。也许算法最后会清空重用列表。

于 2021-07-16T22:42:41.743 回答