Can I create a mutable fragment & mut [u8] from one byte (u8)?

Sometimes I want to read one byte from std::io::Read er. If I try to do this:

 use std::io::{self, Read}; fn main() { let mut byte: u8 = 0; io::stdin().read(&mut byte).unwrap(); println!("byte: {}", byte); } 

I get the following error (which is understandable since byte 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 that I can save byte as a simple u8 and just take a piece of it, which I can then pass read() ? The obvious way to make this code work is to use an array of length 1:

 use std::io::{self, Read}; fn main() { let mut byte: [u8; 1] = [0]; io::stdin().read(&mut byte).unwrap(); println!("byte: {}", byte[0]); } 

But this is a strange feeling in the rest of the code, and it would be more natural to use one u8 rather than [u8; 1] [u8; 1] [u8; 1] [u8; 1] what should I index in.

If it is not possible to create a slice from a simple u8 this is normal, but I do not know if this is possible or not, and I would like to know.

+6
source share
2 answers

Rust 1.28+

slice::from_mut back and 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 this is a strange feeling in the rest of the code, and it would be more natural to use one u8 rather than [u8; 1] [u8; 1] [u8; 1] [u8; 1] what should I index in.

Creating an array of length 1 would be the most natural way to do this:

 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 possibly unsafe to 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 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 two things: a pointer to a memory area and a length. With the length part one, you just need to add the length to the mutable link and bam! you got yourself a bite.

Earlier versions of Rust had ref_slice and mut_ref_slice . They were removed because their utility has not yet been proven (this is not a common problem), but they were safe to call. Functions have been moved to the ref_slice box , so if you want to continue using them, this is the only option.

+13
source

To answer your real question: no, you cannot do this, and they are almost never needed. Even if you cannot get iterability from what is readable, you can just put byte[0] in another variable and use that.

Instead, you can use the Bytes iterator :

 let byte: u8 = io::stdin().bytes().next().unwrap(); 
+4
source

Source: https://habr.com/ru/post/1232921/


All Articles