3个版本
0.1.2 | 2020年12月4日 |
---|---|
0.1.1 | 2020年12月4日 |
0.1.0-alpha | 2020年12月2日 |
#190 在 内存管理
170KB
3K SLoC
generic-vec
可以存储任何位置的项目:切片、数组或堆中的向量!
GenericVec
与Vec
完全兼容,甚至提供了一些仅在std
上的nightly
版本中存在的功能(如GenericVec::drain_filter
),或者更宽松的接口如GenericVec::retain
。实际上,您可以轻松地将一个Vec
转换为HeapVec
并返回!
此crate与no_std
兼容,只需关闭所有默认功能即可。
特性
std
(默认)- 允许您使用分配器,并且alloc
- 允许您使用分配器,用于堆分配存储(如Vec
)nightly
- 允许您使用基于数组的存储([T; N]
)
基本用法
SliceVec
和InitSliceVec
SliceVec
和InitSliceVec
非常相似,您向它们提供一个切片缓冲区,并将它们的所有值存储在该缓冲区中。但它们之间有三个主要区别。
- 您可以将未初始化的缓冲区传递给
SliceVec
- 您只能使用
Copy
类型与InitSliceVec
- 只要您保持在容量范围内(您传递的切片的长度),您就可以自由设置
InitSliceVec
的长度
use generic_vec::{SliceVec, InitSliceVec, uninit_array};
let mut uninit_buffer = uninit_array!(16);
let mut slice_vec = SliceVec::new(&mut uninit_buffer);
assert!(slice_vec.is_empty());
slice_vec.push(10);
assert_eq!(slice_vec, [10]);
let mut init_buffer = [0xae; 16];
let mut slice_vec = InitSliceVec::new(&mut init_buffer);
assert!(slice_vec.is_full());
assert_eq!(slice_vec.pop(), 0xae);
slice_vec.set_len(16);
assert!(slice_vec.is_full());
当然,如果您尝试超出*SliceVec
的容量(您传递的切片的长度),则它将恐慌。
let mut init_buffer = [0xae; 16];
let mut slice_vec = InitSliceVec::new(&mut init_buffer);
slice_vec.push(0);
类型Vec
TypeVec
是一个拥有缓冲区。你可以这样使用:
use generic_vec::{TypeVec, gvec};
let mut vec: TypeVec<u32, [u32; 4]> = gvec![1, 2, 3, 4];
assert_eq!(vec, [1, 2, 3, 4]);
vec.try_push(5).expect_err("Tried to push past capacity!");
第二个参数指定缓冲区类型,可以是任何你想要的类型。只关心类型的大小。还有一个默认的第三个参数,但只有在了解 UninitBuffer
文档后才能使用。
这个框架的一个巧妙副作用是,你也可以为空大小的类型获得高效的 GenericVec
,大小仅为 usize
!这个功能可以在稳定版本的 no_std
上使用。
ArrayVec
和 InitArrayVec
ArrayVec
和 InitArrayVec
与切片版本类似,但由于它们拥有自己的数据,因此可以自由移动,不受限制。你也可以不传递现有缓冲区就创建一个新的 ArrayVec
,这与切片版本不同。
在稳定版本中,你可以使用 ArrayVec
或 InitArrayVec
来构建类型。在 nightly
中,你可以使用类型别名 ArrayVec
和 InitArrayVec
。一旦 min_const_generics
进入稳定版,这些宏将被弃用。
在稳定版本中,唯一限制是只能使用 InitArrayVec
的容量达到 32。即 InitArrayVec![i32; 33]
不起作用。ArrayVec
没有这个限制,因为它建立在 TypeVec
之上。
use generic_vec::ArrayVec;
let mut array_vec = ArrayVec::<i32, 16>::new();
array_vec.push(10);
array_vec.push(20);
array_vec.push(30);
assert_eq!(array_vec, [10, 20, 30]);
ArrayVec
和 InitArrayVec
之间的区别与它们的切片版本相同。
ZSVec
use generic_vec::ZSVec;
struct MyType;
let mut vec = ZSVec::new();
vec.push(MyType);
vec.push(MyType);
vec.push(MyType);
assert_eq!(vec.len(), 3);
assert_eq!(std::mem::size_of_val(&vec), std::mem::size_of::<usize>());
alloc
HeapVec
只是 Vec
,但建立在 GenericVec
之上,这意味着你可以免费获得 GenericVec
的所有功能!但这就需要启用 alloc
或 std
功能。
use generic_vec::{HeapVec, gvec};
let mut vec: HeapVec<u32> = gvec![1, 2, 3, 4];
assert_eq!(vec.capacity(), 4);
vec.extend(&[5, 6, 7, 8]);
assert_eq!(vec, [1, 2, 3, 4, 5, 6, 7, 8]);
vec.try_push(5).expect_err("Tried to push past capacity!");
nightly
在 nightly
- 对
InitArrayVec
长度的限制消失了。 - 许多函数/方法变为
const fn
类型 - 启用了一些优化
- 一些诊断变得更好
关于文档的说明:如果功能存在于 Vec
中,则文档要么与 Vec
完全相同,要么略作修改以更好地适应 GenericVec
关于实现的说明:实现的大部分内容直接来自 Vec
,所以感谢出色的参考 std
!
当前版本:0.1.2
许可证:MIT/Apache-2.0