私は同時に2つのイテレータを処理する関数を実装しようとしています。このコールバックは、(bool, bool)
タプルを返すことで、各ステップでどのイテレータを進めるかを制御できます。イテレータは私の使用例でバッファを参照するので、ファンクション(Iterator::next
と同じですが、追加の有効期間パラメータが必要です)を使用してstdlibからIterator
の特性を実装することはできません。コールバックで `zip`のような関数で借用チェッカーの問題
// An iterator-like type, that returns references to itself
// in next_ref
struct RefIter {
value: u64
}
impl RefIter {
fn next_ref<'a>(&'a mut self) -> Option<&'a u64> {
self.value += 1;
Some(&self.value)
}
}
// Iterate over two RefIter simultaneously and call a callback
// for each pair. The callback returns a tuple of bools
// that indicate which iterators should be advanced.
fn each_zipped<F>(mut iter1: RefIter, mut iter2: RefIter, callback: F)
where F: Fn(&Option<&u64>, &Option<&u64>) -> (bool, bool)
{
let mut current1 = iter1.next_ref();
let mut current2 = iter2.next_ref();
loop {
let advance_flags = callback(¤t1, ¤t2);
match advance_flags {
(true, true) => {
current1 = iter1.next_ref();
current2 = iter2.next_ref();
},
(true, false) => {
current1 = iter1.next_ref();
},
(false, true) => {
current2 = iter1.next_ref();
},
(false, false) => {
return
}
}
}
}
fn main() {
let mut iter1 = RefIter { value: 3 };
let mut iter2 = RefIter { value: 4 };
each_zipped(iter1, iter2, |val1, val2| {
let val1 = *val1.unwrap();
let val2 = *val2.unwrap();
println!("{}, {}", val1, val2);
(val1 < 10, val2 < 10)
});
}
error[E0499]: cannot borrow `iter1` as mutable more than once at a time
--> src/main.rs:28:28
|
22 | let mut current1 = iter1.next_ref();
| ----- first mutable borrow occurs here
...
28 | current1 = iter1.next_ref();
| ^^^^^ second mutable borrow occurs here
...
42 | }
| - first borrow ends here
error[E0499]: cannot borrow `iter2` as mutable more than once at a time
--> src/main.rs:29:28
|
23 | let mut current2 = iter2.next_ref();
| ----- first mutable borrow occurs here
...
29 | current2 = iter2.next_ref();
| ^^^^^ second mutable borrow occurs here
...
42 | }
| - first borrow ends here
error[E0499]: cannot borrow `iter1` as mutable more than once at a time
--> src/main.rs:32:28
|
22 | let mut current1 = iter1.next_ref();
| ----- first mutable borrow occurs here
...
32 | current1 = iter1.next_ref();
| ^^^^^ second mutable borrow occurs here
...
42 | }
| - first borrow ends here
error[E0499]: cannot borrow `iter1` as mutable more than once at a time
--> src/main.rs:35:28
|
22 | let mut current1 = iter1.next_ref();
| ----- first mutable borrow occurs here
...
35 | current2 = iter1.next_ref();
| ^^^^^ second mutable borrow occurs here
...
42 | }
| - first borrow ends here
私はそれが不平を言う理由を理解、それを回避する方法を見つけることができません。私はその件に関する助けに感謝します。
playgroundのこのスニペットにリンクします。
最後の 'iter1.advance();'は 'iter2.advance();'ですか? – Douglas
@Douglasそれは確かにそれのように見えるが、私はOPのロジックにちょうど従っていた。おそらく彼らは彼らの狂気への方法を持っていたでしょう。 – Shepmaster
このような狂気には方法はありません。実際のコードから削除するときにコピー&ペーストエラーが発生します。その特定のバージョンの 'zip'の理由は、fastqレコード(DNAスニペットに関する情報)が2つの異なるファイルに分割されることが多いからです。しかし時にはそれらのファイルには、通常のジップが同期しなくなる不一致なレコードがいくつか含まれています。ところで、イテレータを分割することは素晴らしいアイデアです。ストリーミング・イテレーターというキーワードがなくなってしまったと思います。ありがとう。 – aseyboldt