【发布时间】:2021-05-27 03:42:34
【问题描述】:
我正在实现一个位向量。我的问题是 - 如何实现切片功能?这是我的代码(我在代码之后尝试过的事情):
use core::ops::Range;
use std::ops::Index;
pub struct Bitvec {
vec: Vec<u8>,
}
impl Bitvec {
pub fn new(capacity: usize) -> Bitvec {
Bitvec {
vec: Vec::with_capacity(capacity),
}
}
pub fn bit_at(&self, index: usize) -> bool {
let mask = 2u8.pow(7 - (index % 8) as u32);
self.vec.get(index / 8).unwrap() & mask == mask
}
pub fn push(&mut self, val: u8) {
self.vec.push(val);
}
}
impl Index<usize> for Bitvec {
type Output = bool;
fn index(&self, index: usize) -> &Self::Output {
match self.bit_at(index) {
true => &true,
false => &false,
}
}
}
impl Index<Range<usize> for Bitvec {
type Output = ??;
fn index(&self, index: Range<usize>) -> &Self::Output {
//What should go here?
}
}
fn main() {
let mut bv = Bitvec::new(20);
bv.push(0b1011_0011);
assert_eq!(bv.bit_at(0), true);
assert_eq!(bv.bit_at(1), false);
assert_eq!(bv[0], true);
assert_eq!(bv[1], false);
let slice = bv[2..4]; //should return a slice that represents the two bits of [11]
}
Bitvec 的 Index
我尝试过的事情:
-
创建一个包含开始和结束的结构 BitSlice 并返回它。因为我需要让 BitSlice 持有对 Bitvec 的引用,所以我最终与借用检查器作斗争。也无法从 index(...) 函数返回 &BitSlice。
-
让 Bitvec 拥有一个 BitSlice,但会遇到类似的问题,即 BitSlice 和 Bitvec 相互引用
-
让 Bitvec 拥有一个选项,但也会遇到生命周期问题。
【问题讨论】:
-
有趣的问题!实现范围索引的唯一两种类型是切片和字符串,它们都具有神奇的编译器支持,导致
&[]和&str携带长度以及指向起点的指针。没有它,你必须返回某种类型的你自己的,但由于它必须是一个引用,你不能从index()创建和返回它。我希望一些更有经验的 Rustacean 能回答这个问题。 -
我可以在 Bitvector 上实现一个 get_slice(&self, start:usize, end:usize) ,它返回一个新的 BitSlice 结构,它就是这样工作的。但我似乎无法使用 Index 特征来做到这一点。我想我必须实现一个智能指针来保存底层向量,然后在 Bitvector 和 BitSlice 之间共享它。
-
Rust subreddit 不错:reddit.com/r/rust/comments/4as7gx/…
-
"
Index<Range>对Bitvec的 impl 应该返回什么?"没什么,因为你不应该有。Index用于数据结构中已经存在并且可以引用的东西,但在这里这是不可能的,因为你不能引用值的位。无论您使用多少个智能指针,您都不能只创建一个Bitslice来返回,因为您不知道何时删除它。 -
看看像 Rust 内置的
VecDeque这样的东西,它选择使用make_contiguous和as_slices之类的方法,而不是使用Index<Range>,因为内存中不存在连续切片.
标签: data-structures rust boolean slice