【发布时间】:2018-06-16 04:59:49
【问题描述】:
我有一个&[u8] 并想将其转换为&[u8; 3] 而无需复制。它应该引用原始数组。我该怎么做?
【问题讨论】:
-
[&x[0], &x[1], &x[2]]? -
这是一个 [&u8; 3].
-
你为什么需要那个?
我有一个&[u8] 并想将其转换为&[u8; 3] 而无需复制。它应该引用原始数组。我该怎么做?
【问题讨论】:
[&x[0], &x[1], &x[2]]?
从 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() 来避免写出数组类型的需要,如果你确定切片是足够大。
他们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]
}
【讨论】:
再次强调,如果没有不安全的代码,这将无法完成,因为直到运行时您才知道切片中包含三个元素。
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 之前,这不能在数组的长度上通用。
【讨论】:
unsafe 关键字,这是没有办法的。但这是合理的,因为我们检查切片的长度,编译器信任我们这样做。