【问题标题】:How to convert a slice into an array reference?如何将切片转换为数组引用?
【发布时间】:2018-06-16 04:59:49
【问题描述】:

我有一个&[u8] 并想将其转换为&[u8; 3] 而无需复制。它应该引用原始数组。我该怎么做?

【问题讨论】:

标签: arrays rust slice


【解决方案1】:

从 Rust 1.34 开始,您可以使用 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);
}

【讨论】:

  • 如果你将它传递给一个需要这样一个参数的函数,你也可以使用try_into().unwrap() 来避免写出数组类型的需要,如果你确定切片是足够大。
【解决方案2】:

他们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]
}

【讨论】:

    【解决方案3】:

    再次强调,如果没有不安全的代码,这将无法完成,因为直到运行时您才知道切片中包含三个元素。

    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
        }
    }
    

    在实现const generics 之前,这不能在数组的长度上通用。

    【讨论】:

    • 我对“这不安全”的措辞持怀疑态度。这绝对是安全——只要你检查切片的长度。如果它实际上永远不可能是安全的,那么一开始就不应该写它。这是一个迂腐的论点,但对于 Rust 新手来说,“安全”的概念已经够混乱了,我觉得值得指出。
    • 他的意思可能是“这不可能是不安全的”。
    • 是的,我同意。也许更好的措辞是没有不安全的代码就无法完成
    • 该逻辑不能“在没有不安全代码的情况下完成”,因为 stdlib 必然需要不安全代码,内部使用的所有内容都有。我认为正确的措辞是“这个问题没有完全的解决方案”;它的任何解决方案都必须是部分的,并以某种方式解释切片没有至少 3 个元素的错误情况。
    • @Zorf 我喜欢使用的措辞是区分 safesound。该代码不安全,因为您必须使用 unsafe 关键字,这是没有办法的。但这是合理的,因为我们检查切片的长度,编译器信任我们这样做。
    猜你喜欢
    • 2021-09-04
    • 2019-06-15
    • 2016-08-01
    • 1970-01-01
    • 2022-01-19
    • 2019-03-13
    • 2012-12-28
    相关资源
    最近更新 更多