我正在尝试为字节流实现一个简单的解析器。

当我想重用之前声明的变量时遇到麻烦,

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变量,但是使用上面显示的代码,编译时出现下一个错误:



但是,如果我在使用第二次rdr变量时写了“let mut”,则代码可以编译并正常工作...
let mut rdr = Cursor::new(data_tuple.2.as_slice());

我不明白为什么...我想要的是重用变量而不是再次声明...

我尝试了一些与可变生命周期有关的示例/问题,但没有得到针对我的案例的解决方案...而我发现我不完全了解的解决方案...

最佳答案

这与元组生命周期无关,这只是删除顺序。

当变量在相同范围(即,同一块)中的不同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的引用,并让元组本身删除。

您提到的“修复”是可行的,因为即使每个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没有任何关系。从本质上讲,它几乎与声明两个不同的变量(即rdr2rdr2)以及从此处开始到函数结尾使用ojit_code相同。

关于rust - Tuple的 rust 生命周期问题。,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52919684/

10-10 18:34