我发现使用ndarray crate在不可变数组引用和可变数组引用之间进行减法是不可能的:
#[macro_use]
extern crate ndarray;
use ndarray::Array1;
fn main() {
let a: &Array1<f64> = &array![3.0, 2.0, 1.0];
let b: &mut Array1<f64> = &mut array![1.0, 1.0, 1.0];
let c = a - &b.view(); // This compiles
let d = a - b; // This fails to compile
}
我得到的错误信息是:
let d = a - b;
^ no implementation for `f64 - &mut ndarray::ArrayBase<ndarray::OwnedRepr<f64>, ndarray::Dim<[usize; 1]>>`
我不明白这两种类型的含义,但是有什么特殊原因可以解决这个问题吗?
答案 0 :(得分:2)
&mut
参数未实现Sub
trait in ndarray::ArrayBase
(它用于对其他数组的不可变引用)。不需要它,因为不应修改右手值。第二个操作数是&mut Array<A, D>
,它最终成为弱化为不可变引用的类型不会自动发生的情况之一。不过,您可以明确地重新借用这个值:
let a: &Array1<f64> = &array![3.0, 2.0, 1.0];
let b: &mut Array1<f64> = &mut array![1.0, 1.0, 1.0];
let c = a - &b.view();
let d = a - &*b;
这假设a
和b
是在其他地方获得的。实际上,您可以改为使这些变量拥有数组:
let a: Array1<f64> = array![3.0, 2.0, 1.0];
let mut b: Array1<f64> = array![1.0, 1.0, 1.0];
let c = &a - &b.view();
let d = &a - &b;
答案 1 :(得分:1)
完整的错误消息是:
error[E0277]: the trait bound `f64: std::ops::Sub<&mut ndarray::ArrayBase<ndarray::OwnedRepr<f64>, ndarray::Dim<[usize; 1]>>>` is not satisfied
--> src/main.rs:10:15
|
10 | let d = a - b;
| ^ no implementation for `f64 - &mut ndarray::ArrayBase<ndarray::OwnedRepr<f64>, ndarray::Dim<[usize; 1]>>`
|
= help: the trait `std::ops::Sub<&mut ndarray::ArrayBase<ndarray::OwnedRepr<f64>, ndarray::Dim<[usize; 1]>>>` is not implemented for `f64`
= note: required because of the requirements on the impl of `std::ops::Sub<&mut ndarray::ArrayBase<ndarray::OwnedRepr<f64>, ndarray::Dim<[usize; 1]>>>` for `&ndarray::ArrayBase<ndarray::OwnedRepr<f64>, ndarray::Dim<[usize; 1]>>`
error[E0277]: the trait bound `&mut ndarray::ArrayBase<ndarray::OwnedRepr<f64>, ndarray::Dim<[usize; 1]>>: ndarray::ScalarOperand` is not satisfied
--> src/main.rs:10:15
|
10 | let d = a - b;
| ^ the trait `ndarray::ScalarOperand` is not implemented for `&mut ndarray::ArrayBase<ndarray::OwnedRepr<f64>, ndarray::Dim<[usize; 1]>>`
|
= note: required because of the requirements on the impl of `std::ops::Sub<&mut ndarray::ArrayBase<ndarray::OwnedRepr<f64>, ndarray::Dim<[usize; 1]>>>` for `&ndarray::ArrayBase<ndarray::OwnedRepr<f64>, ndarray::Dim<[usize; 1]>>`
第一条错误信息对我来说非常模糊,但第二条更具启发性:
没有为`&amp; mut ndarray :: ArrayBase
实现特征ndarray::ScalarOperand
出现此错误的原因是Rust在匹配特征时不执行强制:如果某个类型U
和T
强制要求U
,则不构成T
的实施(直接从the Nomicon复制)
没有进入ndarray内部,这是一个重现同样问题的最小例子:
trait MyShape {}
fn foo<T: MyShape>(x: T) -> T {
x
}
impl<'a> MyShape for &'a i32 {}
fn main() {
let mut num = 1;
let arg: &mut i32 = &mut num;
foo(arg);
}
结果:
error[E0277]: the trait bound `&mut i32: MyShape` is not satisfied
--> src/main.rs:12:5
|
12 | foo(arg);
| ^^^ the trait `MyShape` is not implemented for `&mut i32`
|
= help: the following implementations were found:
<&'a i32 as MyShape>
= note: required by `foo`