首页 文章

错误:xxx的寿命不够长

提问于
浏览
0

这有效:

fn user_add<'x>(data: &'x Input, db: &'x mut Database<'x>) -> HandlerOutput {
    //let input: UserAddIn = json::decode(&data.post).unwrap();
    //let username = input.username.as_bytes();
    //let password = input.password.as_bytes();
    db.put(b"Hi", b"hello");
    //db.delete(username);
    Ok("Hi".to_string())
}

这不起作用:

fn user_add<'x>(data: &'x Input, db: &'x mut Database<'x>) -> HandlerOutput {
    //let input: UserAddIn = json::decode(&data.post).unwrap();
    //let username = input.username.as_bytes();
    //let password = input.password.as_bytes();
    let my_str = "hi".to_string();
    let username = my_str.as_bytes();
    db.put(username, b"hello");
    //db.delete(username);
    Ok("Hi".to_string())
}

编译器输出:

src/handlers.rs:85:17: 85:23 error: `my_str` does not live long enough
src/handlers.rs:85      let username = my_str.as_bytes();
                                       ^~~~~~
src/handlers.rs:80:77: 89:2 note: reference must be valid for the lifetime 'x as defined on the block at 80:76...
src/handlers.rs:80 fn user_add<'x>(data: &'x Input, db: &'x mut Database<'x>) -> HandlerOutput {
src/handlers.rs:81      //let input: UserAddIn = json::decode(&data.post).unwrap();
src/handlers.rs:82      //let username = input.username.as_bytes();
src/handlers.rs:83      //let password = input.password.as_bytes();
src/handlers.rs:84      let my_str = "hi".to_string();
src/handlers.rs:85      let username = my_str.as_bytes();
                   ...
src/handlers.rs:84:32: 89:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 84:31
src/handlers.rs:84      let my_str = "hi".to_string();
src/handlers.rs:85      let username = my_str.as_bytes();
src/handlers.rs:86      db.put(username, b"hello");
src/handlers.rs:87      //db.delete(username);
src/handlers.rs:88      Ok("Hi".to_string())
src/handlers.rs:89 }

我在Rust看到了几个关于生命的问题,我认为这本书并不清楚 . 我仍然使用生命作为试验和错误 . 这个具体案例让我感到困惑,因为我已经多次尝试与编译器作斗争,这只是我得到的最后一个错误 . 如果您有一些Rust技能,请考虑在书中编辑有关生命周期的部分 .

2 回答

  • 3

    在第一种情况下, b"Hi" 是字节文字,类型为 &'static [u8] ,表示“具有无限生命期的 u8 切片” . 函数 put 需要一些生命周期 'x ,因为 'static live比任何生命都大,Rust很乐意使用它 .

    在第二种情况下

    let my_str = "hi".to_string();
    let username = my_str.as_bytes();
    

    username 是对 my_str 的内部缓冲区的引用,并且不能超过它 . 编译器抱怨,因为 put 的第一个参数应该具有生命周期 'x ,它比 my_str (本地到 user_add )更宽 . Rust不允许你这样做,因为 db 会在函数调用结束时指向悬空数据:

    user_add(input, &mut db);
    // `my_str` was local to `user_add` and doesn't exist anymore
    // if Rust had allowed you to put it in `db`, `db` would now contain some invalid data here
    
  • 1

    感谢@mcarton回答错误发生的原因 . 在这个答案中,我希望它明确如何解决它 .


    编译器的代码生成是完美的,但错误信息对我来说非常混乱 .

    问题出在我做的另一个库中,恰好是一个数据库 . 数据库结构包含一个包含切片的条目 . 切片的生命周期设置为:

    struct Entry<'a> {
        key: &'a [u8],
        value: &'a [u8],
    }
    
    pub struct Database<'a> {
        file: File,
        entries: Vec<Entry<'a>>,
    }
    

    这意味着切片所拥有的数据需要比数据库结构更长寿 . username 变量超出范围,但持有对它的引用的数据库仍然存在 . 因此,这意味着数据库必须保存比它长的数据,比如静态变量,这会使数据库无用 .

    图书馆编译好了 . 但错误显示在其他地方 .

    解决方案是将矢量切换为矢量,因为矢量不是指针 . 向量可以比数据库少 .

    struct Entry {
        key: Vec<u8>,
        value: Vec<u8>,
    }
    
    pub struct Database {
        file: File,
        entries: Vec<Entry>,
    }
    

相关问题