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

関数のドキュメントにあります:

変換関数に渡されるリストは一時的なものであり、その関数内でのみ有効であることに注意してください。スナップショットを作成しない限り、保存したり、何らかの方法でエスケープしたりしないでください。

実装の詳細として、この高次関数は、ウィンドウの各要素に対して同じリスト インスタンスを再利用し、その間にそれをクリア/再入力します。これにより、多くのリストを割り当てる必要がなくなります。

これを変換関数の戻り値として渡すことで、リスト インスタンスがエスケープしないように警告されているため、エスケープできます。

3 番目の例では、 を使用してリストのコピーを返しているtoList()ため、正しく機能します。

シーケンスでこれを行うと、関数が内部的にリストとその他の反復可能な型を異なる方法で処理するため、結果は異なります。おそらく、アルゴリズムは最後に再利用されたリストを空にします。

于 2021-07-16T22:42:41.743 に答える