我的许多功能中都有以下模式:
use std::sync::{Arc, Mutex};
struct State {
value: i32
}
fn foo(data: Arc<Mutex<State>>) {
let state = &mut data.lock().expect("Could not lock mutex");
// mutate `state`
}
&mut *data.lock().expect("Could not lock mutex")
重复一遍又一遍,所以我想将其重构为一个函数,以便编写类似
let state = get_state(data);
我尝试了以下方法:
fn get_state(data: &Arc<Mutex<State>>) -> &mut State {
&mut data.lock().expect("Could not lock mutex")
}
不能编译为:
错误:无法返回引用临时值的值
这使我相信data.state.lock().expect("...")
价值回报。但是,我可以看到在该游乐场通过多次foo
调用使状态发生了变化。
这里发生了什么?为什么我看似简单的重构无法编译?
编辑:
我希望以下内容也能起作用:
fn get_state<'a>(data: &'a Arc<Mutex<State>>) -> &'a mut State {
let state: &'a mut State = &mut data.lock().expect("Could not lock mutex");
state
}
但是它失败了:
|
12 | fn get_state<'a>(data: &'a Arc<Mutex<State>>) -> &'a mut State {
| -- lifetime `'a` defined here
13 | let state: &'a mut State = &mut data.lock().expect("Could not lock mutex");
| ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
| |
| type annotation requires that borrow lasts for `'a`
14 | state
15 | }
| - temporary value is freed at the end of this statement
为什么返回的任何内容的生存期都不lock
匹配data
参数之一?
该lock()
方法返回MutexGuard
而不是直接引用受保护对象。您可以使用对象引用,因为MutexGuard
实现是Deref
和DerefMut
,但是您仍然需要互斥锁保护在范围内,因为当超出范围时,互斥锁将被释放。同样,对内部对象的引用的生存期也与互斥保护的生存期绑定在一起,因此编译器将不允许您在没有互斥保护的情况下使用对内部对象的引用。
您可以在宏或方法中提取常用逻辑,但应返回MutexGuard而不是对内部对象的引用。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句