【问题标题】:why is the result of "windowed" different?为什么“窗口化”的结果不同?
【发布时间】:2021-07-16 21:32:58
【问题描述】:

带列表的代码:

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]]

请解释

【问题讨论】:

    标签: kotlin collections windowed


    【解决方案1】:

    在函数的文档中:

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-24
      • 1970-01-01
      • 2015-09-14
      • 2010-10-29
      • 2012-07-28
      • 2013-03-10
      • 1970-01-01
      相关资源
      最近更新 更多