这有效:
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技能,请考虑在书中编辑有关生命周期的部分。
答案 0 :(得分: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 :(得分: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>,
}