首页 文章

Tuple生锈的问题 .

提问于
浏览
1

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

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

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

错误[E0597]:data_tuple.2的活动时间不够长 - > src / main.rs:80:23 | 80 | rdr = Cursor :: new(data_tuple.2.as_slice()); | ^^^^^^^^^^^^借来的 Value 不够长...... 104 | } | - data_tuple.2在这里仍然借用了| = note:范围中的值按照创建它们的相反顺序删除错误:由于先前的错误而中止

但是如果我在使用第二次rdr变量时写“let mut”,代码编译并正常工作......

let mut rdr = Cursor::new(data_tuple.2.as_slice());

我不明白为什么......我想要的是重复使用变量来再次声明它...

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

1 回答

  • 1

    这与元组生命周期无关,这只是下降顺序 .

    当变量在同一范围内的单独 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 与第一个没有任何联系 . 从本质上讲,它几乎与声明两个不同的变量(例如 rdrrdr2 )相同,并且在此位置使用 rdr2 直到函数结束 .

相关问题