我的 rust 应用程序中有一堆函数,它们都获取一个互斥体作为参数,其中包含一个选项。我需要该互斥体,因为函数将在线程中执行,并且我需要选项,因为该值不是在开始时设置的,必须在运行时的某个时刻进行初始化。
现在,所有这些函数都从提取该值开始,如下所示:
fn do_something(state_mutex: Mutex<Option<MyDataStruct>>) -> Result<(), MyCustomError> {
let state_option = state_mutex.lock()?;
let state = state_option.as_mut().ok_or(MyCustomError::new("value was None"))?;
// rest of the function...
}
现在,为了保持干燥,我如何将这些代码行放入单个函数中,如下所示:
fn do_something(state_mutex: Mutex<Option<MyDataStruct>>) -> Result<(), MyCustomError> {
let state = get_state_from_mutex(&mut state_mutex);
// rest of the function...
}
我不知道如何编写那个
get_state_from_mutex
函数。
我发现最干净的方法如下:
fn get_state_from_mutex(state_mutex: &mut Mutex<Option<MyDataStruct>>) -> Result<&mut MyDataStruct, MyCustomError>
Ok(&mut state_mutex
.get_mut()?
.ok_or(MyCustomError::new("value was None"))?
)
}
但这失败了
cannot return value referencing temporary value
returns a value referencing data owned by the current function
那么我如何将该临时值的所有权赋予我的
do_something
函数呢?或者有更好的方法来做到这一点吗?
我也可以使用宏,但我觉得应该可以为此创建一个函数。
谢谢你
编辑:
这里是来自 Cargo / rustc 的错误消息:
error[E0515]: cannot return value referencing temporary value
--> src/commands.rs:8:2
|
8 | Ok(&mut state_mutex.get_mut()?.ok_or(MyCustomError::new("value was None"))?)
| ^^^^^^^^-------------------------------------------------------------------^
| | |
| | temporary value created here
| returns a value referencing data owned by the current function
error[E0507]: cannot move out of a mutable reference
--> src/commands.rs:8:10
|
8 | Ok(&mut state_mutex.get_mut()?.ok_or(MyCustomError::new("value was None"))?)
| ^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `std::option::Option<MyDataStruct>`, which does not implement the `Copy` trait
感谢@ChayminFriedman,我能够像这样解决它:
fn get_state_from_mutex(state_mutex: &mut Mutex<Option<MyDataStruct>>) -> Result<&mut MyDataStruct, MyCustomError>
Ok(state_mutex
.get_mut()?
.as_mut()
.ok_or(MyCustomError::new("value was None"))?
)
}
as_mut()
将 &mut Option<T>
转换为 Option<&mut T>
,因此该函数可以返回对互斥体内部值的引用,而不是函数拥有的值。