关于rust:std :: op特性” Not”的类型不匹配

Type mismatch for std::op trait “Not”

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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是输出类型时,它可以很好地编译,但是在执行期间似乎吠叫。

这是我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/// 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);
}

最初,代码如下所示:

1
2
3
4
5
6
if mat.data[j][i] != T::zero() {                                                                                                                                                                                            
   if i != j {                                                                                                                                                                                                  
       exchange(mat, i, j);                                                                                                                                                                                      
       break;                                                                                                                                                                                                    
   }                                                                                                                                                                                                            
}

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

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

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


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

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