Can I create a mutable slice &mut [u8] from a single byte (u8)?
To answer your actual question: no, you can’t do that, and there’s almost never any need to. Even if you couldn’t get an iterable out of a readable, you could just put byte[0]
into another variable and use that.
Instead, you can use the Bytes
iterator:
let byte: u8 = io::stdin().bytes().next().unwrap();
Rust 1.28+
slice::from_mut
is back and it's stable!
use std::{
io::{self, Read},
slice,
};
fn main() {
let mut byte = 0;
let bytes_read = io::stdin().read(slice::from_mut(&mut byte)).unwrap();
if bytes_read == 1 {
println!("read byte: {:?}", byte);
}
}
Rust 1.0+
But that's kinda weird feeling throughout the rest of the code, and it would be more natural to use a single
u8
rather than a[u8; 1]
that I have to index into.
Creating an array of length 1 would be the most natural way of doing it:
use std::io::{self, Read};
fn main() {
let mut bytes = [0];
let bytes_read = io::stdin().read(&mut bytes).unwrap();
let valid_bytes = &bytes[..bytes_read];
println!("read bytes: {:?}", valid_bytes);
}
However, it is possible to unsafely create a slice from a reference to a single value:
use std::io::{self, Read};
use std::slice;
fn mut_ref_slice<T>(x: &mut T) -> &mut [T] {
// It's important to wrap this in its own function because this is
// the only way to tell the borrow checker what the resulting slice
// will refer to. Otherwise you might get mutable aliasing or a
// dangling pointer which is what Rust is trying to avoid.
unsafe { slice::from_raw_parts_mut(x, 1) }
}
fn main() {
let mut byte = 0u8;
let bytes_read = io::stdin().read(mut_ref_slice(&mut byte)).unwrap();
if bytes_read != 0 {
println!("byte: {}", byte);
}
}
Remember that a slice is basically two things: a pointer to an area of memory and a length. With a slice of length one, you simply need to add a length to a mutable reference and bam! you got yourself a slice.
Earlier versions of Rust had the ref_slice
and mut_ref_slice
functions. They were removed because their utility was not yet proven (this isn't a common problem), but they were safe to call. The functions were moved to the ref_slice crate, so if you'd like to continue using them, that's one possibility.