5个不稳定版本
0.2.1 | 2019年4月25日 |
---|---|
0.2.0 | 2019年4月23日 |
0.1.1 | 2019年4月15日 |
0.0.2 | 2019年4月15日 |
0.0.1 | 2019年4月15日 |
#452 in 内存管理
25KB
369 行
vecshard
在O(1)时间内分割Vec。
您可以使用Vec
的Vec::split_off
方法将其分割成两个,但由于大多数分配器不能直接分割分配,这需要为第二个Vec
分配空间,甚至更糟糕的是,需要复制相关元素,这需要O(n)时间。您还可以使用Vec::split_at
或Vec::split_at_mut
将其分割成切片,但这不会给您提供可以随意移动或移出数据的所有权数据。
此crate提供了一种将Vec
分割成两个类似Vec的VecShard
的方法,这两个方法在常数时间内运行。但要注意的是,VecShard
使用引用计数来确定最后一个被丢弃。只有当最后一个被丢弃时,原始Vec
的内存才会被释放。然而,碎片中的单个项目在碎片被丢弃时就会丢弃。
此功能通过为Vec
提供的扩展特质ShardExt
来实现。
文档
请参阅docs.rs上的API文档。
基本示例
use vecshard::ShardExt;
let animals = vec!["penguin", "owl", "toucan", "turtle", "spider", "mosquitto"];
// split the vec into 2 shards
let (cool_animals, uncool_animals) = animals.split_inplace_at(4);
// shards can be indexed as usual
assert_eq!(cool_animals[3], "turtle");
assert_eq!(uncool_animals[0], "spider");
// ..including with a range as index
assert_eq!(cool_animals[1..3], ["owl", "toucan"]);
// they deref into slices, so you can use them as such:
assert_eq!(cool_animals.len(), 4);
assert!(uncool_animals.ends_with(&["mosquitto"]));
// shards can also be split up again:
let (cool_birds, cool_reptiles) = cool_animals.split_inplace_at(3);
assert_eq!(*cool_birds, ["penguin", "owl", "toucan"]);
assert_eq!(*cool_reptiles, ["turtle"]);
转换
碎片可以自由地从From
和Into
转换成Vec。请注意,后者可能需要分配,如果还有其他碎片也使用碎片分配。
let vec = vec![1, 2, 3];
let shard = VecShard::from(vec);
let vec2 : Vec<_> = shard.into();
迭代
要遍历一个VecShard
,你有几种选择。VecShard<T>
自身就是一个可以排空的Iterator
,并返回拥有
let mut shard = VecShard::from(vec!['y', 'e', 'e', 't']);
assert_eq!(Some('y'), shard.next());
assert_eq!(Some('e'), shard.next());
assert_eq!(*shard, ['e', 't']);
可选功能
默认情况下,此crate没有依赖,但如果你想要序列化和反序列化VecShard
,你可以像这样启用serde
功能
[dependencies.vecshard]
optional = true
version = "0.2.1"
依赖
~170KB