我有一个未知大小的数组,我想获得该数组的一部分并将其转换为静态大小的数组:
fn pop(barry: &[u8]) -> [u8; 3] {
barry[0..3] // mismatched types: expected `[u8, ..3]` but found `&[u8]`
}
Run Code Online (Sandbox Code Playgroud)
我该怎么做?
Luk*_*odt 32
这个答案使用不稳定的TryInto
功能!
您可以使用全新的&[u8; 3]
特性(截至2018年6月仍然不稳定)轻松完成此操作:
fn pop(barry: &[u8]) -> [u8; 3] {
barry.try_into().expect("slice with incorrect length")
}
Run Code Online (Sandbox Code Playgroud)
但更好的是:没有必要克隆你的阵列!实际上可以&[u8]
从一个barry
:
fn pop(barry: &[u8]) -> &[u8; 3] {
barry.try_into().expect("slice with incorrect length")
}
Run Code Online (Sandbox Code Playgroud)
正如其他答案中所提到的,如果长度$N
不是3 ,你可能不想恐慌,所以你应该返回一个TryFrom
或类似的东西来优雅地处理这个错误.
这可以归功于TryInto
相关特征的这些impl(其中只是1到32之间的整数)&[u8; 3]
:
impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N]
type Error = TryFromSliceError;
impl<'a, T: Copy> TryFrom<&'a [T]> for [T; $N]
type Error = TryFromSliceError;
Run Code Online (Sandbox Code Playgroud)
Mat*_* M. 18
感谢@malbarbo,我们可以使用这个辅助函数:
use std::convert::AsMut;
fn clone_into_array<A, T>(slice: &[T]) -> A
where
A: Default + AsMut<[T]>,
T: Clone,
{
let mut a = A::default();
<A as AsMut<[T]>>::as_mut(&mut a).clone_from_slice(slice);
a
}
Run Code Online (Sandbox Code Playgroud)
获得更整洁的语法:
fn main() {
let original = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let e = Example {
a: clone_into_array(&original[0..4]),
b: clone_into_array(&original[4..10]),
};
println!("{:?}", e);
}
Run Code Online (Sandbox Code Playgroud)
只要T: Default + Clone
.
如果您知道您的类型实现Copy
,您可以使用此表单:
use std::convert::AsMut;
fn copy_into_array<A, T>(slice: &[T]) -> A
where
A: Default + AsMut<[T]>,
T: Copy,
{
let mut a = A::default();
<A as AsMut<[T]>>::as_mut(&mut a).copy_from_slice(slice);
a
}
Run Code Online (Sandbox Code Playgroud)
panic!
如果目标数组和传入的切片不具有相同的长度,则两种变体都将成立.
mwh*_*ker 15
这是一个与您要求的类型签名相匹配的函数.
fn pop(barry: &[u8]) -> [u8; 3] {
[barry[0], barry[1], barry[2]]
}
Run Code Online (Sandbox Code Playgroud)
但由于barry
可能只有少于三个元素,你可能想要返回一个Option<[u8; 3]>
而不是一个[u8; 3]
.
fn pop(barry: &[u8]) -> Option<[u8; 3]> {
if barry.len() < 3 {
None
} else {
Some([barry[0], barry[1], barry[2]])
}
}
Run Code Online (Sandbox Code Playgroud)
pah*_*olg 14
我建议使用crate arrayref,它有一个方便的宏来做这件事.
请注意,使用此包,您可以创建对数组的引用&[u8; 3]
,因为它不会克隆任何数据!
如果您确实要克隆数据,那么您仍然可以使用宏,但最后调用clone:
#[macro_use]
extern crate arrayref;
fn pop(barry: &[u8]) -> &[u8; 3] {
array_ref!(barry, 0, 3)
}
Run Code Online (Sandbox Code Playgroud)
要么
#[macro_use]
extern crate arrayref;
fn pop(barry: &[u8]) -> [u8; 3] {
array_ref!(barry, 0, 3).clone()
}
Run Code Online (Sandbox Code Playgroud)
Lev*_*ans 10
您可以手动创建阵列并将其返回.
如果您想获得比3个元素更多(或更少)的元素,这个函数可以轻松扩展.
请注意,如果切片太小,则数组的结束项将为0.
fn pop(barry: &[u8]) -> [u8; 3] {
let mut array = [0u8; 3];
for (&x, p) in barry.iter().zip(array.iter_mut()) {
*p = x;
}
array
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
17441 次 |
最近记录: |