ベクトルを繰り返し処理しても、ループ本体がベクトルを勝手に変更してはならないことは明らかです。これにより、バグが発生しやすいイテレータの無効化が防止されます。
ただし、すべての種類の突然変異が反復子の無効化につながるわけではありません。次の例を参照してください。
let mut my_vec: Vec<Vec<i32>> = vec![vec![1,2], vec![3,4], vec![5,6]];
for inner in my_vec.iter_mut() { // <- or .iter()
// ...
my_vec[some_index].push(inner[0]); // <-- ERROR
}
このような変更は のイテレータを無効にしませんがmy_vec
、許可されていません。の特定の要素への参照が無効になる可能性がmy_vec[some_index]
ありますが、いずれにしてもそのような参照は使用しません。
これらの質問がよくあることは承知しており、説明を求めているわけではありません。このループを取り除くことができるように、これをリファクタリングする方法を探しています。私の実際のコードでは、巨大なループ本体があり、これをうまく表現しないとモジュール化できません。
これまでに考えたこと:
- ベクトルを でラップし
Rc<RefCell<...>>
ます。RefCell
はイテレータによって借用され、ループ本体がそれを借用しようとすると失敗するため、これは実行時にまだ失敗すると思います。 - 一時的なベクトルを使用して将来のプッシュを蓄積し、ループの終了後にそれらをプッシュします。これは問題ありませんが、オンザフライでプッシュするよりも多くの割り当てが必要です。
- 安全でないコード、およびポインタのいじり。
Iterator
ドキュメントに記載されているものは役に立ちません。itertoolsをチェックアウトしましたが、どちらも役に立たないようです。while
外側のベクトルへの参照を利用する反復子を使用する代わりに、ループとインデックスを使用します。これは問題ありませんが、イテレータとアダプタを使用できません。この外側のループを取り除き、 を使用したいだけですmy_vec.foreach(...)
。
これを適切に実行できるイディオムやライブラリはありますか? 安全でない関数は、ポインターを公開しない限り問題ありません。