为什么要使用嵌套块?

4

我刚在base64 crate中遇到了这段代码:

 buffer.resize(decoded_len_estimate, 0);

let bytes_written;
{
    let buffer_slice = &mut buffer.as_mut_slice()[starting_output_len..];
    bytes_written = decode_helper(input_bytes, num_chunks, config, buffer_slice)?;
}

buffer.truncate(starting_output_len + bytes_written);

请参见 https://github.com/marshallpierce/rust-base64/blob/b63975f0a3d2e724c611bf6cd7213ae6bcb065a3/src/decode.rs#L165-L169。为什么要使用这种声明变量bytes_written的方式,然后再使用这个嵌套的块?这种写法解决了什么问题?为什么不直接使用这段代码?
 buffer.resize(decoded_len_estimate, 0);

let buffer_slice = &mut buffer.as_mut_slice()[starting_output_len..];
let bytes_written = decode_helper(input_bytes, num_chunks, config, buffer_slice)?  
buffer.truncate(starting_output_len + bytes_written);

有人可以帮我解决这个问题吗?


2
一个原因是,这可以防止buffer_slice泄漏到外部命名空间。 - Tim Roberts
一方面,它们限制了变量的作用域,有时是由于编译器处理生命周期的方式而必需的。至于为什么在特定情况下使用它们,我不知道,因为似乎实际上并不必要(没有它们代码仍然可以编译)。 - Herohtar
2
这里没有展示的一个原因是,如果您有一个变量只需要在设置期间可变,然后在此后应该是不可变的,您可以在块内执行设置,然后将不可变变量分配给块的“返回值”。 - BallpointBen
1个回答

19

这段代码是在四年前编写的 (2017年12月5日),在 NLL (非词法生命周期) 到来之前 (2018年12月6日)。使用 NLL 后,借用检查器会将引用视为“活跃”,直到其最后一次使用为止。但是在没有 NLL 的情况下,引用被视为在作用域结束时(其 drop)才失效。由于 buffer_slice 可变地借用了 buffer,并且最后一行也这样做了,在 NLL 之前的借用检查器中会出现错误,这可能就是为什么他们引入了该块,以为 buffer_slice 创建一个新的作用域,使其在下一次借用 buffer 之前被释放。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接