Testing 为什么要在循环后重置一些变量?

Testing 为什么要在循环后重置一些变量?,testing,rust,Testing,Rust,不久前我读完了Rust编程语言,为了自学Rust,我正在创建一个简单的http服务器 在一个旨在解析和[u8]并创建HttpRequest对象的函数中,我注意到应该解析标题的循环实际上并没有更新用于跟踪解析状态的一些变量: pub fn parse_请求(缓冲区:&[u8])->结果0; 断言!(16,pos); let(lel,pos)=下一个请求行(请求,pos); 断言!(“内容长度:3”,字符串::from_utf8_lossy(lel)); 断言!(lel.len()>0); 断言!(

不久前我读完了Rust编程语言,为了自学Rust,我正在创建一个简单的http服务器

在一个旨在解析
和[u8]
并创建
HttpRequest
对象的函数中,我注意到应该解析标题的循环实际上并没有更新用于跟踪解析状态的一些变量:

pub fn parse_请求(缓冲区:&[u8])->结果0;
断言!(16,pos);
let(lel,pos)=下一个请求行(请求,pos);
断言!(“内容长度:3”,字符串::from_utf8_lossy(lel));
断言!(lel.len()>0);
断言!(35,pos);
let(lel,pos)=下一个请求行(请求,pos);
断言!(“”,字符串::from_utf8_lossy(lel));
断言!(lel.len()==0);
断言!(37,pos);
let(lel,pos)=下一个请求行(请求,pos);
断言!(“”,字符串::from_utf8_lossy(lel));
断言!(lel.len()==0);
let(lel,pos)=下一个请求行(请求,pos);
断言!(“”,字符串::from_utf8_lossy(lel));
断言!(lel.len()==0);
let(lel,pos)=下一个请求行(请求,pos);
断言!(“lel”,字符串::from_utf8_lossy(lel));
断言!(lel.len()==3);
}
#[测试]
fn测试解析请求(){
让mut request=String::from(“GET/HTTP/1.1\r\n”);
请求。push_str(“内容长度:3\r\n”);
请求。push_str(“\r\n”);
请求。推送街(“lel”);
let request=request.as_bytes();
匹配解析请求(&U请求){
Ok(http_请求)=>{
assert_eq!(http_request.method,“GET”);
断言(http_request.path,“/”);
assert_eq!(http_request.version,“http/1.1”);
},
错误(41;)=>{
println!(“失败”);
}
}
}
注释行只是为了显示发生了什么,这就是我看到这个输出的地方:


    Finished test [unoptimized + debuginfo] target(s) in 0.53s
     Running target/debug/deps/rweb-6bbc2a3130f7e3d9

running 4 tests
test http::testing::test_next_req_line ... ok
test http::testing::test_parse_header ... ok
test http::testing::test_parse_method_path_and_version ... ok
--- parsed method path version  ---
--- got next line: 35, Content-Length: 3 ---
LOOP
--- parsed header: Content-Length: 3 ---
--- got next line: 37,  ---
--- got next line: 39, lel ---
LOOP
--- got next line: 37,  ---
10
test http::testing::test_parse_request ... ok

test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

似乎
while
循环没有重新分配
curr\u req\u reader\u pos
变量,但对我来说,期望循环更新这些变量并解析每个头是完全合理的。然而,正如任何人在测试中看到的那样,它在循环之外工作得很好

我不明白为什么我目前对生锈的理解会发生这种情况,为什么会发生这种情况?

你不是在循环中“重新分配”变量,而是创建新的变量,暂时隐藏外部变量,然后在迭代结束时超出范围

下面是一个关于简化伪代码的示例:

let x0 = 0
{
    let x1 = x0 + 1 // original x gets shadowed, x = 1
    let x2 = x1 + 1 // x1 gets shadowed, x = 2
} // both x1 and x2 go out of scope
let x1 = x0 + 1 // x = 1
您不是在循环中“重新分配”变量,而是创建新的变量,这些变量暂时隐藏外部变量,然后在迭代结束时超出范围。是的。摆脱循环中的“let”s。Let将在内部作用域中创建一个同名的新变量。正如答案所解释的,这是“阴影”。若要重新分配,请执行“x=某事物”