元组生锈的生命周期问题。
Problems with Tuple's lifetime in rust.
我正在尝试为字节流实现一个简单的解析器。
当我想重用我之前声明的变量时遇到了麻烦,
fn read_data(asn_data: &mut Cursor<&[u8]>) -> Result<(u8, u8, Vec<u8>), Err> {
let total_len = asn_data.get_ref().len();
if total_len < 2 {
return Err(1);
}
let d_type = asn_data.read_u8().unwrap();
let d_len = asn_data.read_u8().unwrap();
if (asn_data.position() + d_len as u64) > total_len as u64 {
return Err(2);
}
let mut buf = vec![0; d_len as usize];
match asn_data.read_exact(&mut buf) {
Err(e) => Err(e),
Ok(()) => Ok((d_type, d_len, buf)),
}
}
fn parse_request(request: &[u8]) -> Option<u8> {
if request.len() == 0 {
return None;
}
let mut rdr = Cursor::new(request);
let data_tuple = read_data(&mut rdr).unwrap();
println!("{:02?}", data_tuple.2);
rdr = Cursor::new(data_tuple.2.as_slice());
let data_tuple = read_data(&mut rdr).unwrap();
println!("{:02x?}", data_tuple.2);
Some(1)
}
在 parse_request 函数中我想重用 rdr 变量,但是使用上面显示的代码我在编译时遇到下一个错误:
error[E0597]: data_tuple.2
does not live long enough -->
src/main.rs:80:23
| 80 | rdr = Cursor::new(data_tuple.2.as_slice());
| ^^^^^^^^^^^^ borrowed value does not live long enough ... 104 | }
| - data_tuple.2
dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
error: aborting due to previous error
然而,如果我在第二次使用 rdr 变量时写 "let mut",代码编译并工作正常......
let mut rdr = Cursor::new(data_tuple.2.as_slice());
我不明白为什么...我想要的是重用变量而不是再次声明它...
我尝试了一些与可变生命周期相关的examples/issues,但我没有得到适合我的案例的解决方案...我发现我不完全理解的解决方案...
这与元组生命周期无关,这只是丢弃顺序。
当变量在同一作用域(即同一块)中的单独let
语句中定义时,它们将按反向 顺序删除。查看您的代码,我们可以看到:
let mut rdr = Cursor::new(request);
let data_tuple = read_data(&mut rdr).unwrap();
因此,data_tuple
将首先被删除 ,而 rdr
仍然存在。这很糟糕,因为 rdr
必须引用元组。最简单的解决方法是交换它们的定义:
let data_tuple: (u8, u8, Vec<u8>);
let mut rdr = Cursor::new(request);
data_tuple = read_data(&mut rdr).unwrap();
这样,rdr
将首先被删除,释放对 data_tuple
的引用并让元组本身被删除。
你提到的 "fix" 有效,因为每个 let
语句都定义了新变量,即使已经使用了相同的名称,并且现有变量立即被遗忘。所以,当你写:
let mut rdr = Cursor::new(request);
let data_tuple = read_data(&mut rdr).unwrap();
let mut rdr = Cursor::new(data_tuple.2.as_slice());
第二个rdr
与第一个没有任何关系。从本质上讲,它与声明两个不同的变量几乎相同,比如说,rdr
和 rdr2
,并从这里开始使用 rdr2
直到函数结束。
我正在尝试为字节流实现一个简单的解析器。
当我想重用我之前声明的变量时遇到了麻烦,
fn read_data(asn_data: &mut Cursor<&[u8]>) -> Result<(u8, u8, Vec<u8>), Err> {
let total_len = asn_data.get_ref().len();
if total_len < 2 {
return Err(1);
}
let d_type = asn_data.read_u8().unwrap();
let d_len = asn_data.read_u8().unwrap();
if (asn_data.position() + d_len as u64) > total_len as u64 {
return Err(2);
}
let mut buf = vec![0; d_len as usize];
match asn_data.read_exact(&mut buf) {
Err(e) => Err(e),
Ok(()) => Ok((d_type, d_len, buf)),
}
}
fn parse_request(request: &[u8]) -> Option<u8> {
if request.len() == 0 {
return None;
}
let mut rdr = Cursor::new(request);
let data_tuple = read_data(&mut rdr).unwrap();
println!("{:02?}", data_tuple.2);
rdr = Cursor::new(data_tuple.2.as_slice());
let data_tuple = read_data(&mut rdr).unwrap();
println!("{:02x?}", data_tuple.2);
Some(1)
}
在 parse_request 函数中我想重用 rdr 变量,但是使用上面显示的代码我在编译时遇到下一个错误:
error[E0597]:
data_tuple.2
does not live long enough --> src/main.rs:80:23 | 80 | rdr = Cursor::new(data_tuple.2.as_slice()); | ^^^^^^^^^^^^ borrowed value does not live long enough ... 104 | } | -data_tuple.2
dropped here while still borrowed | = note: values in a scope are dropped in the opposite order they are createderror: aborting due to previous error
然而,如果我在第二次使用 rdr 变量时写 "let mut",代码编译并工作正常......
let mut rdr = Cursor::new(data_tuple.2.as_slice());
我不明白为什么...我想要的是重用变量而不是再次声明它...
我尝试了一些与可变生命周期相关的examples/issues,但我没有得到适合我的案例的解决方案...我发现我不完全理解的解决方案...
这与元组生命周期无关,这只是丢弃顺序。
当变量在同一作用域(即同一块)中的单独let
语句中定义时,它们将按反向 顺序删除。查看您的代码,我们可以看到:
let mut rdr = Cursor::new(request);
let data_tuple = read_data(&mut rdr).unwrap();
因此,data_tuple
将首先被删除 ,而 rdr
仍然存在。这很糟糕,因为 rdr
必须引用元组。最简单的解决方法是交换它们的定义:
let data_tuple: (u8, u8, Vec<u8>);
let mut rdr = Cursor::new(request);
data_tuple = read_data(&mut rdr).unwrap();
这样,rdr
将首先被删除,释放对 data_tuple
的引用并让元组本身被删除。
你提到的 "fix" 有效,因为每个 let
语句都定义了新变量,即使已经使用了相同的名称,并且现有变量立即被遗忘。所以,当你写:
let mut rdr = Cursor::new(request);
let data_tuple = read_data(&mut rdr).unwrap();
let mut rdr = Cursor::new(data_tuple.2.as_slice());
第二个rdr
与第一个没有任何关系。从本质上讲,它与声明两个不同的变量几乎相同,比如说,rdr
和 rdr2
,并从这里开始使用 rdr2
直到函数结束。