我可以从单个字节 (u8) 创建可变切片 &mut [u8] 吗? [英] Can I create a mutable slice &mut [u8] from a single byte (u8)?

查看:82
本文介绍了我可以从单个字节 (u8) 创建可变切片 &mut [u8] 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时我想从 std::io::Reader 读取单个字节.如果我尝试这样做:

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

我收到以下错误(很明显,因为 byte 不是切片):

错误[E0308]:类型不匹配-->src/main.rs:6:22|6 |io::stdin().read(&mut byte).unwrap();|^^^^^^^^^ 预期切片,找到 u8|= 注意:预期类型`&mut [u8]`找到类型`&mut u8`

有没有办法可以将 byte 保持为一个简单的 u8,然后只取一部分,然后我可以将其传递给 read()?使此代码工作的明显方法是使用长度为 1 的数组:

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

但是在整个代码的其余部分,这种感觉有点奇怪,使用单个 u8 而不是 [u8; 会更自然.1] 我必须索引.

如果无法从简单的 u8 创建切片,那没关系,但我不知道是否可行,但我想知道.

解决方案

Rust 1.28+

slice::from_mut 回来了,而且很稳定!

使用 std::{io::{自我,阅读},片,};fn 主(){让 mut 字节 = 0;让 bytes_read = io::stdin().read(slice::from_mut(&mut byte)).unwrap();如果 bytes_read == 1 {println!("读取字节:{:?}", byte);}}

Rust 1.0+

<块引用>

但是在整个代码的其余部分,这种感觉有点奇怪,使用单个 u8 而不是 [u8; 会更自然.1] 我必须索引.

创建一个长度为 1 的数组是最自然的方法:

use std::io::{self, Read};fn 主(){让 mut 字节 = [0];让 bytes_read = io::stdin().read(&mut bytes).unwrap();让 valid_bytes = &bytes[..bytes_read];println!("读取字节数:{:?}", valid_bytes);}

但是,可能不安全地从对单个值的引用创建切片:

use std::io::{self, Read};使用 std::slice;fn mut_ref_slice(x: &mut T) ->&mut [T] {//将 this 包装在自己的函数中很重要,因为这是//告诉借用检查器结果切片是什么的唯一方法//会参考.否则你可能会得到可变别名或//悬空指针,这是 Rust 试图避免的.不安全 { slice::from_raw_parts_mut(x, 1) }}fn 主(){让 mut 字节 = 0u8;让 bytes_read = io::stdin().read(mut_ref_slice(&mut byte)).unwrap();如果 bytes_read != 0 {println!("byte: {}", byte);}}

请记住,切片基本上是两件事:指向内存区域的指针和长度.使用长度为 1 的切片,您只需将长度添加到可变引用和 bam!你得到了自己的一片.

早期版本的 Rust 有 ref_slicemut_ref_slice 函数.它们被删除是因为它们的实用性尚未得到证实(这不是一个常见问题),但它们可以安全调用.这些函数已移至 ref_slice crate,因此如果您想继续使用它们,这是一种可能性.

Sometimes I want to read a single byte from a std::io::Reader. 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 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::{self, 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!

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.

这篇关于我可以从单个字节 (u8) 创建可变切片 &amp;mut [u8] 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆