E0597: does not live long enough の原因と直し方
ブロックの中で作った値への参照を、そのブロックの外に持ち出そうとするとE0597エラーになります。参照先の値は、参照そのものと同じかそれより長く生存していなければなりません。
エラーメッセージの読み方
error[E0597]: `inner` does not live long enough
E0597- エラーコード — `rustc --explain E0597` で詳しい説明が見られます
`inner` does not live long enough- 詳細メッセージ — 何が問題だったか
このエラーが出る典型パターン
パターン1
1 fn main() { 2 let outer = 10; 3 let r; 4 { 5 let inner = 5; 6 r = &inner; ^ 7 } 8 println!("{}", r); 9 }
error[E0597]: `inner` does not live long enough
innerはブロックを抜けると破棄されます。破棄された後の参照を使おうとするとE0597エラーになります。
直し方: &inner を &outer にします。
広告
広告スロット(未設定)
パターン2
1 fn main() { 2 let base = 100; 3 let r; 4 { 5 let temp = 1; 6 r = &temp; ^ 7 } 8 println!("{}", r); 9 }
error[E0597]: `temp` does not live long enough
参照先の値は、その参照が使われる期間よりも長く生きていなければなりません。
直し方: &temp を &base にします。
パターン3
1 fn main() { 2 let global_count = 0; 3 let r; 4 { 5 let local_count = 5; 6 r = &local_count ; ^ 7 } 8 println!("{}", r); 9 }
error[E0597]: `local_count` does not live long enough
ブロックの中だけで生きる変数への参照を外に持ち出すことは、ダングリング参照を防ぐために禁止されています。
直し方: &local_count を &global_count にします。
パターン4
1 fn main() { 2 let outer_id = 7; 3 let r; 4 { 5 let inner_id = 3; 6 r = &inner_id; ^ 7 } 8 println!("{}", r); 9 }
error[E0597]: `inner_id` does not live long enough
外側で宣言されたouter_idはmain関数の終わりまで生きるので、参照を持ち出しても安全です。
直し方: &inner_id を &outer_id にします。
パターン5
1 fn main() { 2 let outer_score = 50; 3 let r; 4 { 5 let inner_score = 9; 6 r = &inner_score; ^ 7 } 8 println!("{}", r); 9 }
error[E0597]: `inner_score` does not live long enough
このチェックはコンパイル時に行われるため、実行前に確実にダングリング参照を防げます。
直し方: &inner_score を &outer_score にします。
よくある誤解
「参照さえ保持していれば、元の値が破棄されても参照経由でアクセスできるはず」という思い込みは誤りです。Rustはダングリング参照(実体が消えた後の参照)を防ぐため、参照先の生存期間を厳密にチェックします。
まとめ
E0597: does not live long enoughは上級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。