Rustの借用とライフタイムがさっぱりわからん
Q&A
解決したいこと
自身が保持するVectorへの参照を保持することができない。
集合NとSがあり、それらの集合から1つずつ選択した組み合わせを保持したいができない。
発生している問題・エラー
error[E0502]: cannot borrow `pairs.selected` as immutable because it is also borrowed as mutable
--> src\main.rs:82:25
|
69 | pairs.make_pairs()
| ----- mutable borrow occurs here
...
82 | for (idx, p) in pairs.selected.iter().enumerate() {
| ^^^^^^^^^^^^^^
| |
| immutable borrow occurs here
| mutable borrow later used here
For more information about this error, try `rustc --explain E0502`.
error: could not compile `prac_lifetime` (bin "prac_lifetime") due to 1 previous error
該当するソースコード
struct N {
n: i32,
}
struct S {
s: String,
}
struct Pair<'a> {
n: &'a N,
s: &'a S,
}
struct Pairs<'a> {
selected: Vec<Pair<'a>>,
ns: Vec<N>,
ss: Vec<S>,
}
impl<'a> Pair<'a> {
fn new(n: &'a N, s: &'a S) -> Pair<'a> {
Pair { n, s }
}
}
impl<'a> Pairs<'a> {
fn new(ns: Vec<N>, ss: Vec<S>) -> Pairs<'a> {
Pairs {
selected: Vec::new(),
ns,
ss,
}
}
fn min_len(&self) -> usize {
let vec_len = vec![self.ns.len(), self.ss.len()];
*vec_len.iter().min().unwrap()
}
fn make_pairs(&'a mut self) {
for i in 0..self.min_len() {
let pair = Pair::new(&self.ns[i], &self.ss[i]);
println!("pair : ({}, {})", pair.n.n, pair.s.s);
self.selected.push(pair);
}
}
}
fn main() {
let ns = vec![
N { n: 1 },
N { n: 2 },
N { n: 3 },
N { n: 4 },
N { n: 5 },
N { n: 6 },
];
let ss = vec![
S { s: "a".to_string() },
S { s: "b".to_string() },
S { s: "c".to_string() },
S { s: "d".to_string() },
];
let mut pairs = Pairs::new(ns, ss);
{
// 一応スコープを分けたが無駄だった。
pairs.make_pairs();
}
// 関数に切り出さなければコンパイルが通る
// for i in 0..pairs.min_len() {
// let pair = Pair::new(&pairs.ns[i], &pairs.ss[i]);
// println!("pair : ({}, {})", pair.n.n, pair.s.s);
// pairs.selected.push(pair);
// }
// 以下をコメントアウトすればコンパイルが通る
{
// 一応スコープを分けたが無駄だった。
// error[E0502]: cannot borrow `pairs.pairs` as immutable because it is also borrowed as mutable
for (idx, p) in pairs.selected.iter().enumerate() {
println!("pair[{}] : ({}, {})", idx, p.n.n, p.s.s);
}
}
}
自分で試したこと
- 関数に切り出さなければ意図したとおりになる
- 後続の表示部分をコメントアウトすればコンパイルできるが、以降使用できないのは困る