如何创建堆栈分配的类向量容器? [英] How can I create a stack-allocated vector-like container?

查看:49
本文介绍了如何创建堆栈分配的类向量容器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你将如何创建一个堆栈分配的类向量容器,它可以包含的元素数量有固定的上限?您可以在下面看到我对此的尝试,但它无法编译:

How would you go about creating a stack-allocated vector-like container with some fixed upper limit on the number of elements it can contain? You can see my attempt at this below, but it doesn't compile:

// The following is at crate level
#![feature(unsafe_destructor)]

use std::mem;
use std::ptr;
use std::slice::Iter;

pub struct StackVec<T> {
    buf: [T; 10],
    len: usize,
}

impl<T> StackVec<T> {
    pub fn new() -> StackVec<T> {
        StackVec {
            buf: unsafe { mem::uninitialized() },
            len: 0,
        }
    }

    pub fn iter(&self) -> Iter<T> {
        (&self.buf[..self.len]).iter()
    }

    pub fn push(&mut self, value: T) {
        unsafe { ptr::write(self.buf.get_mut(self.len).unwrap(), value); }
        self.len += 1;
    }

    pub fn pop(&mut self) -> Option<T> {
        if self.len == 0 {
            None
        } else {
            unsafe {
                self.len -= 1;
                Some(ptr::read(self.buf.get(self.len).unwrap()))
            }
        }
    }
}

#[unsafe_destructor]
impl<T> Drop for StackVec<T>
    where T: Drop
{
    fn drop(&mut self) {
        for elem in self.iter() {
            unsafe { ptr::read(elem); }
        }
        unsafe { mem::forget(self.buf); } // ERROR: [1]
    }
}

这是我得到的编译时错误:
[1] 错误:无法移出类型 stackvec::StackVec,它定义了 Drop trait

This is the compile-time error I get:
[1] error: cannot move out of type stackvec::StackVec<T>, which defines the Drop trait

推荐答案

我已经编写了一个实现,我将重点介绍一下.

I've written an implementation, and I'll go over the highlights.

使用特征(称为Array)来抽象不同的数组大小.它需要提供原始指针,以便我们可以将数组用作后备存储.

Use a trait (called Array) to abstract over different array sizes. It needs to provide raw pointers so that we can use the array as backing storage.

/// Trait for fixed size arrays.
pub unsafe trait Array {
    /// The array's element type
    type Item;
    unsafe fn new() -> Self;
    fn as_ptr(&self) -> *const Self::Item;
    fn as_mut_ptr(&mut self) -> *mut Self::Item;
    fn capacity() -> usize;
}

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆