Если ваш срез содержит Copy
типов, вы можете использовать From
/ Into
для выполнения построения:
pub struct Foo<T> {
pub data: Box<[T]>,
}
impl<T> Foo<T> {
fn from_slice(slice: &[T]) -> Foo<T>
where
T: Copy,
{
Foo { data: slice.into() }
}
}
Если ваши данные Clone
, то вы можете использовать to_vec
+ into_boxed_slice
:
impl<T> Foo<T> {
fn from_slice(slice: &[T]) -> Foo<T>
where
T: Clone,
{
Foo { data: slice.to_vec().into_boxed_slice() }
}
}
представляется неправильным создание Vec
в качестве прокси для клона
You arenне клонируемся здесь.Когда вы клонируете тип T
, вы получаете тип T
обратно.Вы начинаете с &[T]
и хотите получить Box<[T]>
, а не [T]
(которого у вас не может быть).
Создание коробочного среза через Vec
означает, что вы временно берете 3 целых числа машинного размера вместо 2;вряд ли это будет проблемой производительности по сравнению с объемом выполненного выделения.
Я согласен с ответом starblue , что сохранение Vec<T>
, вероятно, проще для большинства случаев, но я допускаючто в некоторых случаях полезно иметь коробочный срез.
См. также:
Iпредположим, что есть причина, по которой vec!
является макросом
Публичная реализация vec!
является общедоступной:
macro_rules! vec {
($elem:expr; $n:expr) => (
$crate::vec::from_elem($elem, $n)
);
($($x:expr),*) => (
<[_]>::into_vec(box [$($x),*])
);
($($x:expr,)*) => (vec![$($x),*])
}
Это действительно только макросдля удобства синтаксиса (и потому что он использует ключевое слово unstable box
);он принимает аргументы, создает массив, упаковывает его, приводит к преобразованию в штучный фрагмент, а затем преобразует в Vec
.