使用 IndexMut [duplicate] 时,在编译时无法知道类型为“[bool]”的值的大小

the size for values of type `[bool]` cannot be known at compilation time, when using IndexMut [duplicate]

提问人:keymasta 提问时间:7/23/2023 更新时间:7/23/2023 访问量:47

问:

我正在尝试将 Bitmap 类用作布尔值的包装器。因此,我希望能够使用切片进行索引并分配给切片。我来自python背景,所以我习惯了工作。在 python 中,你基本上定义了 indexlen,你就可以开始了。显然,Rust 在类型、所有权和大小方面更为复杂。我真的很喜欢它,并想了解它是如何工作的。请耐心等待我缺乏理解。我是 rust 的菜鸟,但不是编码的菜鸟,尽管我的大部分经验都是动态语言。

实际上,我希望这个结构的行为像一个可迭代对象,即支持索引和切片等。我认为解决方案可能与 Ssized 有关,但我不能肯定地说。

struct Bitmap <const N: usize> {
    bools: [bool;N],
}

impl<const N: usize> Bitmap<N> {
    fn new(bools: [bool;N]) -> Self {
        Bitmap { bools }
    }
}

impl<Idx, const N:usize> std::ops::Index<Idx> for Bitmap<N>
where
    Idx: std::slice::SliceIndex<[bool]>,
{
    type Output = Idx::Output;

    fn index(&self, index: Idx) -> &Self::Output {
        &self.bools[index]
    }
}

impl<const N: usize> std::ops::IndexMut<usize> for Bitmap<N> 
{
    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
        &mut self.bools[index]
    }
}

fn main() {
    let mut test = Bitmap::<6>::new([true, false, true, false, true, false]);
    //Indexing works
    println!("{:?}", test[0]); 
    //Index assignment works
    test[0] = false; 
    //slicing works
    println!("{:?}", &test[1..]); 
    
    //But does not work when you do it like this
    let slice = [2..5].as_slice();
    println!("{:?}", &test[slice])
    //error[E0277]: the type `[bool]` cannot be indexed by `&[std::ops::Range<{integer}>]`
    
    //Slice assign does not work
    //test[0..2] = [false, true]; 
    //error[E0277]: the size for values of type `[bool]` cannot be known at compilation time
}

我尝试将签名更改为类似于索引实现的签名,但出现错误。然后我尝试了一堆随机的东西。他们都没有奏效。impl<const N: usize> std::ops::IndexMut<usize> for Bitmap<N>

蚀索引 切片 包装器

评论

0赞 dath.vg 7/23/2023
你真的需要按切片而不是范围索引吗?如果是这样,您可以实现 SliceIndex,理论上您应该能够按切片进行索引。
0赞 kmdreko 9/3/2023
若要分配给切片中的元素,请使用 。.copy_from_slice()

答:

0赞 Steven Spungin 7/23/2023 #1

你有没有试过从某个范围内获取切片,就像你之前的尝试一样?

let slice = &test[2..5];
println!("{:?}", slice);

现在,同样的方式,但从范围

let range = 2..5; 
let slice = &test[range];
println!("{:?}", slice);

评论

0赞 keymasta 7/24/2023
是的,我注意到这奏效了。我试图让它与赋值一起工作,尽管在 &test[0..3] = [true,true,true]
0赞 harmic 7/23/2023 #2

考虑一下:

    let slice = [2..5].as_slice();
    println!("{:?}", &test[slice]);

第一行创建一个数组,使用值 2,3,4,5 初始化,然后创建整个数组的切片,并将该值绑定到变量 。slice

第二行尝试使用该数组进行索引。但是,Rust 没有提供任何使用从范围 () 生成的值切片来索引布尔数组 () 的方法。就此而言,它没有提供任何使用任何内容切片索引数组的方法。test[bool]&[std::ops::Range<{integer}>]

您可以做的是首先不要将范围转换为数组:

    let range = 2..5;                  // Variable contains range from 2..5
    println!("{:?}", &test[range]);    // Index using range

你可能会问,为什么 Rust 没有提供一种使用任意索引数组索引数组的方法。对于您的示例案例来说,这似乎很简单,但是如果索引不相交(例如,)怎么办?数组是连续的内存块;切片是对连续内存块的引用;范围索引操作返回一个引用基础数组的切片,但如果索引不相交,它会返回什么?[2,7,8]

评论

0赞 harmic 7/23/2023
投反对票的选民会愿意解释投反对票的原因吗?