【问题标题】:How can I copy a shared slice to have a boxed slice?如何复制共享切片以获得盒装切片?
【发布时间】:2019-05-30 06:40:01
【问题描述】:

我有一个容器:

pub struct Foo<T> {
    pub data: Box<[T]>,
}

我想要一种从现有切片中初始化新切片的方法:

impl<T> Foo<T> {
    fn from_slice(slice: &[T]) -> Foo<T> {
        Foo {
            data: Box::new(/* something here */),
        }
    }
}

我想从任何类型的切片创建一个 Foo 实例,来自动态向量或静态字符串。

我想vec! 是一个宏是有原因的,但是有没有办法避免写一个?我想我可以做slice.to_vec().into_boxed_slice(),但创建一个Vec 作为克隆的代理似乎不太正确......

我没有在我的结构中使用Vec,因为data 在容器的生命周期内不应该改变大小。使用Vec 感觉不对,但我可能错了。

【问题讨论】:

  • 我真的不明白请总是分享你做事的目标。为什么不只是pub data: Vec&lt;T&gt;
  • 数据属性不应该在我的容器的生命周期内增长或缩小,所以感觉不对。
  • 为防止更改大小,您不应公开该字段。如果你想允许改变值,你可以实现IndexMut
  • 谢谢!更重要的是我不想要任何开销......在 C++ 中,当更简单的类型完成这项工作时,我不会使用 std::vector。我猜是来自贫穷背景的坏习惯。 ;)
  • 您所指的数组类是静态大小的,也不适合所有情况。至于原始指针...在许多情况下,它们是您唯一的选择:1)您想要 C++ 的软语法优于 C 和 2)无法为您的每一位代码使用 STL 和/或动态分配写。但是感谢您居高临下的语气,它总是受到赞赏。我会看看 ndarray 的实现,作为我的玩具程序的参考,谢谢。

标签: rust


【解决方案1】:

如果你的 slice 包含 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 作为克隆的代理似乎不正确

没有在这里克隆。当你克隆一个类型 T 时,你会得到一个类型 T 回来。您从&amp;[T] 开始并想要获得Box&lt;[T]&gt;,而不是[T](您不能拥有)。

通过Vec 创建一个盒装切片意味着你暂时占用了 3 个机器大小的整数而不是 2 个;与执行的分配量相比,这不太可能是性能问题。

我同意starblue's answer 的观点,即在大多数情况下保留Vec&lt;T&gt; 可能更简单,但我承认有时使用盒装切片很有用。

另见:

我想vec! 是一个宏是有原因的

implementation of vec! 是公开的:

macro_rules! vec {
    ($elem:expr; $n:expr) => (
        $crate::vec::from_elem($elem, $n)
    );
    ($($x:expr),*) => (
        <[_]>::into_vec(box [$($x),*])
    );
    ($($x:expr,)*) => (vec![$($x),*])
}

它实际上只是一个为了语法方便的宏(并且因为它使用了不稳定的box 关键字);它接受参数,创建一个数组,将其装箱,将其强制为装箱切片,然后将其转换为Vec

【讨论】:

    猜你喜欢
    • 2021-08-26
    • 2015-07-28
    • 2021-08-31
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-15
    相关资源
    最近更新 更多