rust 为什么我不能把引用传递给另一个函数,即使读锁没有被删除?

bq3bfh9z  于 2023-02-23  发布在  其他
关注(0)|答案(1)|浏览(109)

参考下面的代码:

use std::collections::HashMap;
use std::sync::RwLock;
    
#[derive(Debug, PartialEq, Eq)]
pub enum RespType<'a> {
    SimpleString(&'a str),
    RespError((&'a str, &'a str)),
    Integer(i32),
    BulkString(Option<&'a str>),
    Array(Vec<RespType<'a>>),
}
    
type Db<'a> = RwLock<HashMap<&'a str, RespType<'a>>>;
pub trait KeyValueStore<'a> {
    fn get_value<'b>(&'a self, key: &'b str, callback: &'a dyn Fn(&'a RespType<'a>));
    fn set_value(&'a mut self, key: &'a str, value: RespType<'a>) -> &'a RespType<'a>;
}
    
impl<'a> KeyValueStore<'a> for Db<'a> {
    fn get_value<'b>(&'a self, key: &'b str, callback: &'a dyn Fn(&'a RespType<'a>)) {
        static null_bulk_string:RespType = RespType::BulkString(None);
        let guard = self.read().unwrap();
        let result = guard.get(key);
        match result{
            Some(v) => {callback(v)}
            None => {callback(&null_bulk_string)}
        };
    }
    
    fn set_value(&'a mut self, key: &'a str, value: RespType<'a>) -> &'static RespType<'static> {
        static ok: RespType = RespType::SimpleString("OK");
        (*self.get_mut().unwrap()).insert(key, value).unwrap();
        &ok
    }
}
    
fn main(){
    
}

错误消息如下所示:

error[E0597]: `guard` does not live long enough
  --> src/main.rs:23:22
   |
19 | impl<'a> KeyValueStore<'a> for Db<'a> {
   |      -- lifetime `'a` defined here
...
23 |         let result = guard.get(key);
   |                      ^^^^^^^^^^^^^^
   |                      |
   |                      borrowed value does not live long enough
   |                      argument requires that `guard` is borrowed for `'a`
...
28 |     }
   |     - `guard` dropped here while still borrowed

读锁在get_value结束时被丢弃,但我似乎无法将其传递给callback,callback显然没有超过读锁的生存期。这是怎么回事?我也不明白错误消息想说什么。有人能解释一下吗?

mfuanj7w

mfuanj7w1#

您对生存期注解的使用有点过了,它将您不希望绑定在一起的东西绑定在一起。

fn get_value<'b>(&'a self, key: &'b str, callback: &'a dyn Fn(&'a RespType<'a>));

这要求回调函数的借位生存期必须与self的借位生存期一样有效,但实际上并非如此。这就是为什么错误消息特别指出“argument requires that guard is borrowed for 'a“(这实际上是一个 * 不可能 * 满足的条件,因为self也具有生存期'a,并且从self获得的任何保护都不会像self那样长)。
解决方案是简单地“不”将这些生命周期绑定在一起:

fn get_value<'b>(&'a self, key: &'b str, callback: &dyn Fn(&RespType));

使用此签名the code compiles
我建议退一步,试着弄清楚你想用生存期注解传达什么,看起来你只是把它们撒得到处都是,而没有确切地理解它们的作用--例如,为什么get_value需要key参数上的'b注解?

相关问题