error[E0716]: temporary value dropped while borrowed
参照中に中間値が破棄された。
殆どの場合、式内の中間値の破棄は、文末 (セミコロンの位置) にて行われる。
そのため、それ以降にその中間値に由来する参照を使用するとエラーになる。
以下では、式内の中間値 Foo::new()
から、メソッド val_ref()
で参照をたどり、その結果を変数 ref_to_temp
へと保存して利用している。しかし、ref_to_temp
へと値を保存する文の文末にてすでに参照先の中間値は破棄されてしまっている。
fn main() {
let ref_to_temp = Foo::new().val_ref();
println!("Value is {}.", *ref_to_temp);
}
struct Foo {
val: i32
}
impl Foo {
fn new() -> Self {
Self { val: 0 }
}
fn val_ref(&self) -> &i32 {
&self.val
}
}
error[E0716]: temporary value dropped while borrowed --> src\main.rs:2:21 | 2 | let ref_to_temp = Foo::new().val_ref(); | ^^^^^^^^^^ - temporary value is freed at the end of this statement | | | creates a temporary value which is freed while still in use 3 | println!("Value is {}.", *ref_to_temp); | ------------ borrow later used here | help: consider using a `let` binding to create a longer lived value | 2 ~ let binding = Foo::new(); 3 ~ let ref_to_temp = binding.val_ref();
エラーメッセージの help
にある通り、中間値をローカル変数に保存する。
借用式 (&x
) の演算対象 (x
) がアドレスでなく通常の値の場合、必要に応じて現在のスコープに値が自動保存され、式の結果はそこへの参照となる。そのためこの場合、中間値を生成した文より後でも、スコープ内ならばその中間値への参照を使える。
つまり、借用式では中間値と参照まわりのエラーはあまり起きない。ただそれでも、中間値の参照を静的参照として利用したりすると、やはりエラーになる。
以下では、借用式内の中間値 Foo::new()
のフィールド val
への参照が、変数 ref_to_temp
から参照できるよう、中間値が自動保存されている。しかし、その中間値は静的に保存されているわけではない。そのため、ref_to_temp
は、関数 use_ref
の引数にはなれない。
fn main() {
let ref_to_temp = &Foo::new().val;
use_ref(ref_to_temp);
}
fn use_ref(arg: &'static i32) {
println!("Value is {}.", *arg);
}
struct Foo {
val: i32
}
impl Foo {
fn new() -> Self {
Self { val: 0 }
}
}
error[E0716]: temporary value dropped while borrowed --> src\main.rs:2:24 | 2 | let ref_to_temp = &Foo::new().val; | ^^^^^^^^^^ creates a temporary value which is freed while still in use 3 | use_ref(ref_to_temp); | -------------------- argument requires that borrow lasts for `'static` 4 | } | - temporary value is freed at the end of this statement