如何在 Rust 中获取定位索引处的位值?

问题描述 投票:0回答:2

我正在尝试执行以下程序。

fn main() {
    let a: u8 = 0b00000001;
    let b: u8 = 0b10101010;
    let c: u8 = 0b00001111;
    let length = a.count_ones() + a.count_zeros();
    for n in 0..length {
        println!("{}", a[n]);
        println!("{}", b[n]);
        println!("{}", c[n]);
    }
}

但我越来越

error[E0608]: cannot index into a value of type `u8` 

rust rust-cargo
2个回答
12
投票

Rust 不提供整数各个位的索引。您需要改用按位运算符:

这将从右侧开始计数(最低有效位到最高有效位):

fn main() {
    let a: u8 = 0b00000001;
    let b: u8 = 0b10101010;
    let c: u8 = 0b00001111;
    let length = a.count_ones() + a.count_zeros();
    for n in 0..length {
        println!("{}", a >> n & 1);
        println!("{}", b >> n & 1);
        println!("{}", c >> n & 1);
    }
}

未提供此功能的原因是

Index
特质的定义如下:

pub trait Index<Idx>
where
    Idx: ?Sized,
{
    type Output: ?Sized;
    fn index(&self, index: Idx) -> &Self::Output;
}

index()
返回一个引用,但引用始终指向字节地址;你不能引用任何一个位。


根据您的实际用例,您可能也对以下板条箱之一感兴趣:


0
投票

您可以将字节转换为位数组,然后使用该数组访问各个位。

将字节转换为位数组

/// Gets the bits of a byte as an array, with the most significant bit
/// at index 0 and the least significant bit at index 7.
/// For example, if the byte is 130, the array will be [1, 0, 0, 0, 0, 0, 1, 0]
fn get_bits_of_byte(byte: u8) -> [u8; 8] {
    let mut bits = [0u8; 8];
    for i in 0..=7 {
        let shifted_byte = byte >> i;
        // Get the rightmost bit of the shifted byte (least significant bit)
        let cur_bit = shifted_byte & 1;
        // For the first iteration, the cur_bit is the
        // least significant bit and therefore we place
        // that bit at index 7 of the array (rightmost bit)
        bits[7 - i] = cur_bit;
    }
    bits
}

您可以在函数中使用以下内容来更好地理解其行为:

println!(
    "Index: {i}, shifted byte: {shifted_byte:08b}. Current bit (with shifted_byte & 1): {cur_bit}"
);

测试功能

这里有一些测试,包括您提供的示例代码。

#[test]
fn test_get_bits_of_byte() {
    let byte = 0b1010_1010;
    let bits = get_bits_of_byte(byte);
    assert_eq!(bits, [1, 0, 1, 0, 1, 0, 1, 0]);

    let byte = 255;
    let bits = get_bits_of_byte(byte);
    assert_eq!(bits, [1, 1, 1, 1, 1, 1, 1, 1]);

    let byte = 3;
    let bits = get_bits_of_byte(byte);
    assert_eq!(bits, [0, 0, 0, 0, 0, 0, 1, 1]);

    let byte = 130;
    let bits = get_bits_of_byte(byte);
    assert_eq!(bits, [1, 0, 0, 0, 0, 0, 1, 0]);
}

#[test]
fn index_bytes() {
    let a: u8 = 0b00000001;
    let b: u8 = 0b10101010;
    let c: u8 = 0b00001111;
    let length = a.count_ones() + a.count_zeros();

    let a_array = get_bits_of_byte(a);
    let b_array = get_bits_of_byte(b);
    let c_array = get_bits_of_byte(c);

    for n in 0..length {
        println!("{}", a_array[n as usize]);
        println!("{}", b_array[n as usize]);
        println!("{}", c_array[n as usize]);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.