実現したいこと
以下のコードで、f(&mut s) を実行しようとするとエラーが発生してコンパイルできません。私が lifetime の仕組みを正確に理解できていないためですが、f のような定義をすると、どうしてエラーになるのかを教えてくださると、大変助かります。
発生している問題・分からないこと
コメントアウトされている f(&mut s) を実行しようとするとコンパイルできません。
エラーメッセージ
error
1 | f(&mut s); 2 | ------ first mutable borrow occurs here 3 | g1(&mut s); 4 | ^^^^^^ 5 | | 6 | second mutable borrow occurs here 7 | first borrow later used here 8
該当のソースコード
Rust
1struct S<'a> { 2 ref_val: &'a mut i32, 3} 4 5impl<'a> S<'a> { 6 fn new(ref_val: &'a mut i32) -> Self { 7 S { 8 ref_val, 9 } 10 } 11} 12 13fn f<'a>(s: &'a mut S<'a>) { 14 *s.ref_val += 1; 15} 16 17fn g1<'a>(s: &'a mut S) { 18 *s.ref_val += 1; 19} 20 21fn g2<'a>(s: &mut S<'a>) { 22 *s.ref_val += 1; 23} 24 25fn g3(s: &mut S) { 26 *s.ref_val += 1; 27} 28 29fn test_1() { 30 let mut val: i32 = 0; 31 let mut s = S::new(&mut val); 32 33// f(&mut s); 34 g1(&mut s); 35 g2(&mut s); 36 g3(&mut s); 37} 38
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
AI にも質問しましたが、g1、g2、g3 で可変参照を複数回利用しているため、エラーになるというような返答で、なかなか良い解答を得ることができていません。
補足
特になし
以下と類似の問題に見えます
メンバ変数への参照は推奨されないようです
同様の状態と解釈されるのでしょう
https://qiita.com/tagawa0525/questions/b879138858e2a3fe73a3
いろいろ考察をしてくださって、ありがとうございます。
教えてくださったコードを見てみてましたが、掲載されているものは、当然にコンパイルが通っていはいけないコードです。Vec の中の要素への参照を保持しようとしていますが、Vec は可変ですので、工夫もなく Vec 内への参照を保持してはいけません。ダングリングポインタが生まれる可能性のあることをしています。該当記事を書いた方は気付いていないようですが、論理エラーがあるプログラムですので、コンパイラがエラーを出すのも当然だと思われます。
言葉足らずですみません。Vec が可変というのは、いわゆる可変参照などではなくて、メモリ内での移動を含めてです。いわゆる自己参照をメンバ変数に持つときには注意が必要、ということを考えていました。
(質問の意味を勘違いしていたので削除します)

回答2件
あなたの回答
tips
プレビュー