如何将切片转换为数组引用?

Son*_*Ex2 4 arrays slice rust

我有一个,&[u8]并希望把它变成一个&[u8; 3]没有复制.它应该引用原始数组.我怎样才能做到这一点?

She*_*ter 10

在夜间Rust中,您可以使用TryFrom/ TryInto:

use std::convert::TryFrom;

fn example(slice: &[u8]) {
    let array = <&[u8; 3]>::try_from(slice);
    println!("{:?}", array);
}

fn example_mut(slice: &mut [u8]) {
    let array = <&mut [u8; 3]>::try_from(slice);
    println!("{:?}", array);
}
Run Code Online (Sandbox Code Playgroud)


blu*_*uss 8

他们的arrayref crate实现了这一点.

这是一个例子,你当然可以用不同的方式使用它:

#[macro_use]
extern crate arrayref;

/// Get the first 3 elements of `bytes` as a reference to an array
/// **Panics** if `bytes` is too short.
fn first3(bytes: &[u8]) -> &[u8; 3] {
     array_ref![bytes, 0, 3]
}
Run Code Online (Sandbox Code Playgroud)


dur*_*a42 6

重新强调一下,如果没有不安全的代码,就无法做到这一点,因为直到运行时才知道切片中有三个元素.

fn slice_to_arr3<T>(slice: &[T]) -> Option<&[T; 3]> {
    if slice.len() == 3 {
        Some(unsafe { &*(slice as *const [T] as *const [T; 3]) })
    } else {
        None
    }
}
Run Code Online (Sandbox Code Playgroud)

在实现const泛型之前,这在数组的长度上不是通用的.

  • 我会为“这不可能是安全的”这句话而狡辩。它绝对是*安全的*——只要你检查切片的长度。如果它真的永远不可能是安全的,那么它首先就不应该被写入。这是一个迂腐的论点,但对于 Rust 新手来说,“安全”的概念已经足够混乱了,我觉得值得指出。 (3认同)
  • @Zorf我喜欢使用的措辞是区分*安全*和*声音*。该代码不安全,因为您必须使用“unsafe”关键字,没有办法解决这个问题。但这是合理的,因为我们检查了切片的长度,正如编译器信任我们所做的那样。 (2认同)