Pregunta ¡Operación binaria! = No se puede aplicar cuando se usan genéricos para un vector de bits


Estoy en el proceso de implementar una clase Bit Vector como ejercicio, sin embargo, solo conociendo a Rust por menos de una semana me encuentro en problemas con el siguiente código:

use std::cmp::Eq;
use std::ops::BitAnd;
use std::ops::Index;
use std::ops::Not;

struct BitVector<S = usize> 
    where S: Sized + BitAnd<usize> + Not + Eq {
    data: Vec<S>,
    capacity: usize
}

impl<S> BitVector<S>
    where S: Sized + BitAnd<usize> + Not + Eq {
    fn with_capacity(capacity: usize) -> BitVector {
        let len = (capacity / (std::mem::size_of::<S>() * 8)) + 1;
        BitVector { data: vec![0; len], capacity: capacity }
    }
}

impl<S> Index<usize> for BitVector<S>
    where S: Sized + BitAnd<usize> + Not + Eq {
    type Output = bool;

    fn index(&self, index: usize) -> &bool {
        let data_index = index / (std::mem::size_of::<S>() * 8);
        let remainder = index % (std::mem::size_of::<S>() * 8);
        (self.data[data_index] & (1 << remainder)) != 0
    }
}

La idea es que S puede ser uno de, por ejemplo u8, u16, u32, u64 y usize para asegurarse de configurarlo para 0 en with_capacity crea un valor de bit para S que consiste en todos los ceros.

El error que recibo es el siguiente:

lib.rs:27:10: 27:50 error: operación binaria != no se puede aplicar al tipo <S as std::ops::BitAnd<usize>>::Output [E0369]
  lib.rs:27 (self.data [data_index] & (1 << remainder))! = 0
                     ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  lib.rs:27:10: 27:50 ayuda: ejecutar rustc --explain E0369 ver una explicación detallada
  lib.rs:27:10: 27:50 nota: una implementación de std::cmp::PartialEq podría faltar para <S as std::ops::BitAnd<usize>>::Output
  lib.rs:27 (self.data [data_index] & (1 << remainder))! = 0                      ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  error: abortar debido a un error anterior
  error: no se pudo compilar bit-vector.


7
2018-06-03 12:00


origen


Respuestas:


Este error particular aquí, en términos simples, significa que el Output de BitAndEn g S y usize no implementa PartialEq. Una solución sería agregar una restricción que Ses BitAnd<usize>s Output es S:

BitAnd<usize, Output = S>

Después de esto, se encontrará con otro error porque está comparando el valor de BitAnd con 0 y no a un valor de tipo S. Para arreglar eso puedes definir tu propio Zero rasgo y usar eso o usar Rust es inestable std::num::Zero y comparar a S::zero().

También tendrás que hacer S: Copy para que haciendo el BitAnd no consume el valor (o agrega S: Clone y clonar explícitamente antes de llamar BitAnd::bitand)

Finalmente, se encontrará con un error que su index debe devolver un &bool mientras regresas bool. Puedes usar el truco bit-vec utiliza para definir 2 estáticas:

static TRUE: bool = true;
static FALSE: bool = false;

y volver &TRUE o &FALSE de index.

Código de trabajo final (en la noche):

#![feature(zero_one)]

use std::cmp::Eq;
use std::num::Zero;
use std::ops::BitAnd;
use std::ops::Index;
use std::ops::Not;

struct BitVector<S = usize>
    where S: Sized + BitAnd<usize, Output = S> + Not + Eq + Copy + Zero
{
    data: Vec<S>,
    capacity: usize,
}

impl<S> BitVector<S>
    where S: Sized + BitAnd<usize, Output = S> + Not + Eq + Copy + Zero
{
    fn with_capacity(capacity: usize) -> BitVector {
        let len = (capacity / (std::mem::size_of::<S>() * 8)) + 1;
        BitVector {
            data: vec![0; len],
            capacity: capacity,
        }
    }
}

static TRUE: bool = true;
static FALSE: bool = false;

impl<S> Index<usize> for BitVector<S>
    where S: Sized + BitAnd<usize, Output = S> + Not + Eq + Copy + Zero
{
    type Output = bool;

    fn index(&self, index: usize) -> &bool {
        let data_index = index / (std::mem::size_of::<S>() * 8);
        let remainder = index % (std::mem::size_of::<S>() * 8);
        if (self.data[data_index] & (1 << remainder)) != S::zero() {
            &TRUE
        } else {
            &FALSE
        }
    }
}

fn main() {
}

5
2018-06-03 13:11



Preguntas populares