此处可能会使用不可变借用,当“guard”被删除并运行“RwLockWriteGuard”类型的“Drop”代码时
Immutable borrow might be used here, when `guard` is dropped and runs the `Drop` code for type `RwLockWriteGuard`
在相同范围内不可变地借用借用的可变引用后,我如何更改它的值?在我的例子中,不可变地借用的部分包含在 Arc<RwLock<T>>
中
我遇到问题的实际片段:
Event::RedrawRequested(_) => {
let mut guard = app.write().unwrap();
let guard = &mut *guard;
// (...)
app.camera_controller.as_mut().unwrap().update_camera(app.camera.as_mut().unwrap(), dt);
dt = frame_start.elapsed();
}
我有一个关于我的问题的最小示例:
use std::{
ops::Deref,
sync::{Arc, RwLock},
};
struct Inner {
inner_number: Option<f32>,
}
struct App {
inner: Arc<RwLock<Inner>>,
outer_number: Option<f32>,
}
impl App {
fn new(inner_number: f32, outer_number: f32) -> Self {
Self {
inner: Arc::new(RwLock::new(Inner {
inner_number: Some(inner_number),
})),
outer_number: Some(outer_number),
}
}
}
impl Deref for App {
type Target = Arc<RwLock<Inner>>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
fn main() {
let mut app = App::new(10.0, 20.0);
{
let mut guard = app.write().unwrap();
let guard = &mut *guard;
guard.inner_number = Some(guard.inner_number.unwrap() + 5.0);
*(app.outer_number.as_mut().unwrap()) *= 2.0;
}
println!("{:?}", app.outer_number);
}
错误:
Compiling playground v0.0.1 (/playground)
error[E0502]: cannot borrow `app.outer_number` as mutable because it is also borrowed as immutable
--> src/main.rs:42:11
|
37 | let mut guard = app.write().unwrap();
| ----------- immutable borrow occurs here
...
42 | *(app.outer_number.as_mut().unwrap()) *= 2.0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
43 | }
| - immutable borrow might be used here, when `guard` is dropped and runs the `Drop` code for type `RwLockWriteGuard`
For more information about this error, try `rustc --explain E0502`.
error: could not compile `playground` due to previous error
到目前为止,我发现有两种方法可以编译您的代码。
解决方案 #1:
fn main() {
let mut app = App::new(10.0, 20.0);
{
{
let mut guard = app.write().unwrap();
let guard = &mut *guard;
guard.inner_number = Some(guard.inner_number.unwrap() + 5.0);
// Drop guard here, which will release the `app` borrow
}
*(app.outer_number.as_mut().unwrap()) *= 2.0;
}
println!("{:?}", app.outer_number);
}
这个之所以有效,是因为 guard
在 *= 2.0
之前被丢弃了。 app
不能在 guard
期间可变地借用一次,在 *= 2.0
期间不可可变地借用一次。永远不能同时以可变方式和不可变方式借用对象。将整个 guard
部分包装在其自己的上下文中可确保 guard
在 *= 2.0
部分之前发布。
解决方案 #2:
fn main() {
let mut app = App::new(10.0, 20.0);
{
// Use app.inner.write instead of app.write
let mut guard = app.inner.write().unwrap();
let guard = &mut *guard;
guard.inner_number = Some(guard.inner_number.unwrap() + 5.0);
*(app.outer_number.as_mut().unwrap()) *= 2.0;
}
println!("{:?}", app.outer_number);
}
之所以有效,是因为 guard
实际上并没有将整个 app
作为参考,而只是 app.inner
成员。由于 *= 2.0
部分仅引用 app.outer_number
,它不会抱怨,因为这两个部分实际上并没有借用同一个对象。
在相同范围内不可变地借用借用的可变引用后,我如何更改它的值?在我的例子中,不可变地借用的部分包含在 Arc<RwLock<T>>
我遇到问题的实际片段:
Event::RedrawRequested(_) => {
let mut guard = app.write().unwrap();
let guard = &mut *guard;
// (...)
app.camera_controller.as_mut().unwrap().update_camera(app.camera.as_mut().unwrap(), dt);
dt = frame_start.elapsed();
}
我有一个关于我的问题的最小示例:
use std::{
ops::Deref,
sync::{Arc, RwLock},
};
struct Inner {
inner_number: Option<f32>,
}
struct App {
inner: Arc<RwLock<Inner>>,
outer_number: Option<f32>,
}
impl App {
fn new(inner_number: f32, outer_number: f32) -> Self {
Self {
inner: Arc::new(RwLock::new(Inner {
inner_number: Some(inner_number),
})),
outer_number: Some(outer_number),
}
}
}
impl Deref for App {
type Target = Arc<RwLock<Inner>>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
fn main() {
let mut app = App::new(10.0, 20.0);
{
let mut guard = app.write().unwrap();
let guard = &mut *guard;
guard.inner_number = Some(guard.inner_number.unwrap() + 5.0);
*(app.outer_number.as_mut().unwrap()) *= 2.0;
}
println!("{:?}", app.outer_number);
}
错误:
Compiling playground v0.0.1 (/playground)
error[E0502]: cannot borrow `app.outer_number` as mutable because it is also borrowed as immutable
--> src/main.rs:42:11
|
37 | let mut guard = app.write().unwrap();
| ----------- immutable borrow occurs here
...
42 | *(app.outer_number.as_mut().unwrap()) *= 2.0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
43 | }
| - immutable borrow might be used here, when `guard` is dropped and runs the `Drop` code for type `RwLockWriteGuard`
For more information about this error, try `rustc --explain E0502`.
error: could not compile `playground` due to previous error
到目前为止,我发现有两种方法可以编译您的代码。
解决方案 #1:
fn main() {
let mut app = App::new(10.0, 20.0);
{
{
let mut guard = app.write().unwrap();
let guard = &mut *guard;
guard.inner_number = Some(guard.inner_number.unwrap() + 5.0);
// Drop guard here, which will release the `app` borrow
}
*(app.outer_number.as_mut().unwrap()) *= 2.0;
}
println!("{:?}", app.outer_number);
}
这个之所以有效,是因为 guard
在 *= 2.0
之前被丢弃了。 app
不能在 guard
期间可变地借用一次,在 *= 2.0
期间不可可变地借用一次。永远不能同时以可变方式和不可变方式借用对象。将整个 guard
部分包装在其自己的上下文中可确保 guard
在 *= 2.0
部分之前发布。
解决方案 #2:
fn main() {
let mut app = App::new(10.0, 20.0);
{
// Use app.inner.write instead of app.write
let mut guard = app.inner.write().unwrap();
let guard = &mut *guard;
guard.inner_number = Some(guard.inner_number.unwrap() + 5.0);
*(app.outer_number.as_mut().unwrap()) *= 2.0;
}
println!("{:?}", app.outer_number);
}
之所以有效,是因为 guard
实际上并没有将整个 app
作为参考,而只是 app.inner
成员。由于 *= 2.0
部分仅引用 app.outer_number
,它不会抱怨,因为这两个部分实际上并没有借用同一个对象。