std :: op特性“ Not”的类型不匹配

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

我正在实现通用矩阵求解器。为此,我利用“ Not”运算符来解决另一个问题,下面将对此进行解释。但是,在测试中调用该函数时,出现以下错误:

error[E0271]: type mismatch resolving `<i32 as std::ops::Not>::Output == bool`                                                                                                                                                                                                                                                                                                                                                                                                           
   --> src/matrix.rs:223:15                                                                                                                                                                                                                                                                                                                                                                                                                                                              
    |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
90  | pub fn reduce<T>(mat: &mut Matrix<T>) -> Result<Matrix<T>, &'static str>                                                                                                                                                                                                                                                                                                                                                                                                     
    |        ------                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
...                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
97  |         + Not<Output = bool>                                                                                                                                                                                                                                                                                                                                                                                                                                                       
    |               ------------- required by this bound in `matrix::reduce`                                                                                                                                                                                                                                                                                                                                                                                                             
...                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
223 |     let res = reduce(&mut mat).unwrap();                                                                                                                                                                                                                                                                                                                                                                                                                                           
    |               ^^^^^^ expected i32, found bool                                                                                                                                                                                                                                                                                                                                                                                                                                      

error: aborting due to previous error  

这特别令人困惑,因为我不确定我还将如何实现Not特征并使其正常运行。当bool是输出类型时,它编译得很好,但是在执行过程中似乎吠叫。

这是我的代码:

/// Performs a reduction operation on a given matrix, giving the reduced row echelon form                                                                                                                                                                                                                                                                                                                                                                                                
pub fn reduce<T>(mat: &mut Matrix<T>) -> Result<Matrix<T>, &'static str>                                                                                                                                                                                                                                                                                                                                                                                                                 
where                                                                                                                                                                                                                         
    T: num_traits::Zero                                                                                                                                                                                                       
        + num_traits::One                                                                                                                                                                                                     
        + Mul<T, Output = T>                                                                                                                                                                                                  
        + Add<T, Output = T>                                                                                                                                                                                                  
        + Sub<T, Output = T>                                                                                                                                                                                                  
        + Not<Output = bool>                                                                                                                                                                                                  
        + Neg<Output = T>                                                                                                                                                                                                     
        + Div<T, Output = T>                                                                                                                                                                                                  
        + Copy,                                                                                                                                                                                                               
{                                                                                                                                                                                                                             
    let exchange = |matrix: &mut Matrix<T>, i: usize, j: usize| {                                                                                                                                                             
        matrix.data.swap(i, j);                                                                                                                                                                                               
    };                                                                                                                                                                                                                        

    let scale = |matrix: &mut Matrix<T>, row: usize, factor: T| {                                                                                                                                                             
        for i in 0..matrix.data[row].len() {                                                                                                                                                                                  
            matrix.data[row][i] = matrix.data[row][i] * factor;                                                                                                                                                               
        }                                                                                                                                                                                                                     
    };                                                                                                                                                                                                                        

    let row_replace = |matrix: &mut Matrix<T>, i: usize, j: usize, factor: T| {                                                                                                                                               
        for k in 0..matrix.data[j].len() {                                                                                                                                                                                    
            matrix.data[j][k] = matrix.data[j][k] + (matrix.data[i][k] * factor);                                                                                                                                             
        }                                                                                                                                                                                                                     
    };                                                                                                                                                                                                                        

    // Reduction steps                                                                                                                                                                                                        
    let n = mat.data.len();                                                                                                                                                                                                   

    for i in 0..n {                                                                                                                                                                                                           
        // Find a pivot point                                                                                                                                                                                                 
        for j in i..n {                                                                                                                                                                                                       
            if !mat.data[j][i] { // <------- Error Here *********                                                                                                                                                                                             
                if i != j {                                                                                                                                                                                                   
                    exchange(mat, i, j);                                                                                                                                                                                      
                    break;                                                                                                                                                                                                    
                }                                                                                                                                                                                                             
            }                                                                                                                                                                                                                 

            if j == n - 1 {                                                                                                                                                                                                   
                return Err("No pivot found")                                                                                                                                                                                  
            }                                                                                                                                                                                                                 
        }                                                                                                                                                                                                                     

        // Put zeros below diagonal                                                                                                                                                                                           
        for j in i + 1..n {                                                                                                                                                                                                   
            row_replace(mat, i, j, -mat.data[j][i] / mat.data[i][i]);                                                                                                                                                         
        }                                                                                                                                                                                                                     
    }                                                                                                                                                                                                                         

    // Back substitution (bottom up)                                                                                                                                                                                          
    for i in (0..n - 1).rev() {                                                                                                                                                                                               
        for j in 0..i {                                                                                                                                                                                                       
            row_replace(mat, i, j, -mat.data[j][i] / mat.data[i][i]);                                                                                                                                                         
        }                                                                                                                                                                                                                     
    }                                                                                                                                                                                                                         

    // Add 1's to the diagonal                                                                                                                                                                                                
    for i in 0..n {                                                                                                                                                                                                           
        scale(mat, i, T::one() / mat.data[i][i]);
    }

    Ok(mat.clone())
}

#[test]
fn it_row_reduces() {
    let mat = Matrix {
        data: vec![vec![2, 1, 4], vec![1, 2, 5]],
        nrows: 2,
        ncols: 3,
    };

    let comp = Matrix {
        data: vec![vec![1, 0, 1], vec![0, 1, 2]],
        nrows: 2,
        ncols: 3,
    };

    let res = reduce(&mut mat).unwrap();
    assert_eq!(res.data, comp.data);
}

最初,代码如下所示:

if mat.data[j][i] != T::zero() {                                                                                                                                                                                             
   if i != j {                                                                                                                                                                                                   
       exchange(mat, i, j);                                                                                                                                                                                      
       break;                                                                                                                                                                                                    
   }                                                                                                                                                                                                             
} 

但是,即使将Not trait添加到函数签名中,该操作也将永远无法执行,并出现以下错误:

binary operation `!=` cannot be applied to type `T`: T 

我想弄清楚我的代码出了什么问题,如果我使用泛型进行比较是生锈时最惯用的方法。任何其他反馈表示赞赏。我也可以提供该结构,我只是想使问题尽可能简短。

rust
1个回答
0
投票

在Rust中,根据参数类型,!既可以用作逻辑“非”,也可以按位“非”。当参数为bool时,它执行逻辑“非”运算;当参数为整数类型时,它按位“非”运算。实现Not<Output = bool>的唯一内置类型是bool

您应坚持使用if mat.data[j][i] != T::zero() {!=PartialEq特性提供。除了T: Not<Output = bool>界外,您需要T: PartialEq<T>或只是T: Eq

© www.soinside.com 2019 - 2024. All rights reserved.