I just came across this piece of code in 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);
See https://github.com/marshallpierce/rust-base64/blob/b63975f0a3d2e724c611bf6cd7213ae6bcb065a3/src/decode.rs#L165-L169
What is the reason for using this style of declaring the variable bytes_written and then use this nested block. What problem does this solve? Why not just use this code:
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);
Can someone help me with that?
This code was written 4 years ago (5 Dec 2017), before NLL (Non-Lexical Lifetimes) arrived (6 Dec 2018). With NLL, the borrow checker consider a reference "alive" until its last use and no more. But without it, a reference is considered alive until the end of the scope (its drop). Since buffer_slice
borrows buffer
mutably, and the last line does that too, the borrow checker pre-NLL would err - and that's probably why they introduced the block, to create a new scope for buffer_slice
so it will be dropped before the next borrow of buffer
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With