以下の2つの関数try_drain_*
が同じ動作をするとは思っていませんが、2番目が問題なく実行されても最初のコンパイルは失敗します。なぜ借用チェッカーはインライン式を拒否しますが、分割フォームを受け入れますか?
struct Container {
map: RefCell<HashMap<i32, i32>>,
}
impl Container {
fn try_drain_inline(&self) {
self.map.borrow_mut().drain();
}
fn try_drain_broken_down(&self) {
let mut guard = self.map.borrow_mut();
guard.drain();
}
}
ボローチェッカーを約try_drain_inline
on the playgroundを文句:
error[E0597]: borrowed value does not live long enough --> src/main.rs:15:5 | 14 | self.map.borrow_mut().drain(); | --------------------- ^temporary value dropped here while still borrowed | | | temporary value created here | = note: values in a scope are dropped in the opposite order they are created
それはtry_drain_broken_down
と罰金であるのに対し。
作成した一時的なデータが破棄される順序に問題があるようです。一時的なものを「手動で」実体化することで、状況が改善されます。
なぜ、借用チェッカーがインラインフォームを拒否し、崩壊したものを受け入れるのですか?
注:インラインバージョンは、次のコードと同等ですので
fn try_pop(&self) -> Option<i32> {
let mut guard = self.map.borrow_mut();
let mut drain = guard.drain();
drain.next().map(|(_, t)| t)
}
おそらく関連しています:https://stackoverflow.com/questions/43590162/when-returning-the-outcome-of-consuming-a-stdinlock-why-was-the-borrow-to-stdin; https://github.com/rust-lang/rust/issues/21114 –
これはおそらくこれに関連します:http://smallcultfollowing.com/babysteps/blog/2017/07/11/non-lexical-lifetimes-draft -rfc-and-prototype-available / – Boiethios