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

时间:2019-10-28 02:33:56

标签: rust

我正在实现通用矩阵求解器。为此,我利用“ 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 

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

1 个答案:

答案 0 :(得分:2)

在Rust中,根据参数类型,<input type="password" id="password" placeholder="Enter Password.."/> <input type="button" value="Login" name="login" onclick="checkPass(document.getElementById('password').value)"/> 既可以用作逻辑“非”,也可以用作按位“非”。当参数为function checkPass(pass){ if(pass == "correct pass"){ alert("Access Granted"); } else { alert("Please check your password"); } } 时,它执行逻辑非,而当参数为整数类型时,它按位非。实现!的唯一内置类型是bool

您应该坚持使用Not<Output = bool>boolif mat.data[j][i] != T::zero() {特性提供。而不是!=的约束,您将需要PartialEq或只是T: Not<Output = bool>