Rust Arc / Mutex尝试宏借用的内容

时间:2019-02-02 06:40:55

标签: rust automatic-ref-counting mutex borrow-checker try-macro

我试图做的若干操作与被跨线程共享的变量,封装在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自动添加到每一行的类型注释的屏幕截图:

CLion screenshot of code snippet

1 个答案:

答案 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())?;