Is there a way to perform the below more idiomatically?
let data: &mut &[u8] = ...
while !data.is_empty() {
let first = data[0];
data = &data[1..];
// do something with data; we may need to perform `data = &data[n..];` here
}
The idea is that we have data.is_empty(), [0] and [1..] that perform quite similar operations. I was wondering if there is something more idiomatic than the above (e.g. in the sense that it produces less instructions)
I need to advance more than one item at times. I also need to store slices of the data, so it is not possible to iterate item by item in this case since into_iter consumes the iterator
let mut data: &[u8] = ...;
while !data.is_empty() {
let (first, rest) = data.split_at(1);
data = rest;
/* do stuff */
}
With destructuring assignments you could also shorten that to
let mut data: &[u8] = ...;
let mut chunk: &[u8] = &[];
while !data.is_empty() {
(chunk, data) = data.split_at(1);
/* do stuff */
}
That's essentially the only way to consume chunks of data at the lower level, but at the higher level there are alternatives, depending on what you need to do. For example, if you just need to handle fixed-sized chunks of data you could use
for chunk in data.chunks(chunk_size) { ... }
Or maybe you are doing deserialization. If your types support serde::{Serialize, Deserialize} and your format has something like
fn f(data:&mut &[u8]) {
while let [first, rest @ .. ] = data {
*data = rest;
// do something with data; we may need to perform `data = &data[n..];` here
}
}