我试图做的若干操作与被跨线程共享的变量,封装在Arc<Mutex>
。由于并非所有操作都可能成功,因此我尝试使用try!
宏或?
运算符来自动传播错误。
下面是我的代码的最小可行的示例:
lazy_static! {
static ref BIG_NUMBER: Arc<Mutex<Option<u32>>> = Arc::new(Mutex::new(Some(174)));
}
pub fn unpack_big_number() -> Result<u32, Box<Error>> {
let big_number_arc = Arc::clone(&BIG_NUMBER);
let mutex_guard_result = big_number_arc.lock();
let guarded_big_number_option = mutex_guard_result?;
let dereferenced_big_number_option = *guarded_big_number_option;
let big_number = dereferenced_big_number_option.unwrap();
// do some subsequent operations
let result = big_number + 5;
// happy path
Ok(result)
}
您会注意到,在声明guarded_big_number_option
的行中,我的末尾有一个?
。此行抛出以下编译器错误(当我将?
替换为.unwrap()
时不会出现此错误:
error[E0597]: `big_number_arc` does not live long enough
--> src/main.rs:32:30
|
7 | let mutex_guard_result = big_number_arc.lock();
| ^^^^^^^^^^^^^^ borrowed value does not live long enough
...
17 | }
| - borrowed value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
现在的问题是,这是我的理解,我并不想使用big_number_arc
超出了其使用寿命。我试图提取潜在PoisonError
包含在结果中。我怎样才能正确地提取错误,使这个传播工作?
此外,如果有帮助,这是我的IDE CLion自动添加到每一行的类型注释的屏幕截图:
答案 0 :(得分:2)
lock()
函数返回LockResult<MutexGuard<T>>
。 Documentation说:
注意,ERR变体还承载相关联的防护件,并且它可以通过into_inner方法
来获取
因此,您实质上是在尝试返回对局部变量的引用(包装到PoisonError
结构中),这显然是错误的。
如何解决?可以将此错误转换为一些与没有这样的参考文献,例如为String
:
let guarded_big_number_option = mutex_guard_result.map_err(|e| e.to_string())?;