Sometimes I want to read a single byte from a std::io::Read
er. If I try to do this:
use std::io;
use std::io::Read;
fn main() {
let mut byte: u8 = 0;
io::stdin().read(&mut byte).unwrap();
println!("byte: {}", byte);
}
I get the following error (which is clear, as byte
is not a slice):
error[E0308]: mismatched types
--> src/main.rs:6:22
|
6 | io::stdin().read(&mut byte).unwrap();
| ^^^^^^^^^ expected slice, found u8
|
= note: expected type `&mut [u8]`
found type `&mut u8`
Is there a way I can keep byte
as a simple u8
and just take a slice of it, which I can then pass to read()
? The obvious way to make this code work is to use an array of length 1:
use std::io;
use std::io::Read;
fn main() {
let mut byte: [u8; 1] = [0];
io::stdin().read(&mut byte).unwrap();
println!("byte: {}", byte[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.
If it's not possible to create a slice from the simple u8
that's okay, but I don't know if it's possible or not and would like to know.
Rust 1.28+
slice::from_mut
is back and it's stable!Rust 1.0+
Creating an array of length 1 would be the most natural way of doing it:
However, it is possible to unsafely create a slice from a reference to a single value:
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
andmut_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.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: