ndarray - Попытка использовать impl AddAssign <ArrayBase>для ArrayBase вызывает ошибку компилятора - PullRequest
0 голосов
/ 09 июля 2020

Я использую ящик ndarray (версия 0.13.1) для векторных и матричных операций, и я обнаружил ошибку, для которой я хотел бы найти объяснение (и решение).

Обратите внимание этого кода:

use ndarray as nd;
fn main() {
    let mut matrix: nd::Array2<f64> = nd::Array::zeros((3, 4));
    let additional: nd::Array2<f64> = nd::Array::ones((3, 4));
    matrix += additional; // <- Compiler error
}

Я предполагаю, что этот код компилируется и работает правильно, поскольку AddAssign<ndarray::ArrayBase реализован для ndarray::ArrayBase ( см. документацию ), и формы совпадают. Верно ...?

Нет. Я получаю две ошибки компилятора для той же (третьей) строки (см. В конце вопроса).

Моя скромная интерпретация этих ошибок заключается в том, что компилятор, похоже, не замечает реализацию AddAssign<BaseArray> для BaseArray - учитывается только AddAssign<B> where B: ScalarOperand (что тоже задокументировано, верно здесь ).

Интересно, не соответствует ли мой код AddAssign<BaseArray> реализация как-то, а если да - в чем еще может быть проблема? Меня также интригует, что компилятор ожидает f64 как правую часть операции += - что может заставить его полностью игнорировать тот факт, что BaseArray действительно ожидается в этой позиции?

Любая помощь был бы очень, очень признателен. Заранее спасибо!

Ошибки:

error[E0271]: type mismatch resolving `<ndarray::data_repr::OwnedRepr<f64> as ndarray::data_traits::RawData>::Elem == ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<f64>, ndarray::dimension::dim::Dim<[usize; 2]>>`
    --> src\main.rs:11:12
    |
11  |     matrix += additional;
    |            ^^ expected `f64`, found struct `ndarray::ArrayBase`
    |
    = note: expected type `f64`
            found struct `ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<f64>, ndarray::dimension::dim::Dim<[usize; 2]>>`
    = note: required because of the requirements on the impl of `std::ops::AddAssign` for `ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<f64>, ndarray::dimension::dim::Dim<[usize; 2]>>`

error[E0277]: the trait bound `ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<f64>, ndarray::dimension::dim::Dim<[usize; 2]>>: ndarray::impl_ops::ScalarOperand` is not satisfied
    --> src\main.rs:11:12
    |
11  |     matrix += additional;
    |            ^^ the trait `ndarray::impl_ops::ScalarOperand` is not implemented for `ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<f64>, ndarray::dimension::dim::Dim<[usize; 2]>>`
    |
    = note: required because of the requirements on the impl of `std::ops::AddAssign` for `ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<f64>, ndarray::dimension::dim::Dim<[usize; 2]>>`

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0271, E0277.
For more information about an error, try `rustc --explain E0271`.

1 Ответ

0 голосов
/ 09 июля 2020

Не существует реализации AddAssign<ArrayBase> для ArrayBase (параметры типа опущены для краткости). Но существует реализация для AddAssign<&ArrayBase>.

Правила автодерефа иногда создают впечатление, что вы можете использовать ссылки или значения как взаимозаменяемые, но этот механизм не t распространяется на реализации трейтов или параметры типа, поэтому вам нужно быть здесь более явным.

Вы можете исправить свой код, передавая по ссылке:

matrix += &additional;

Сообщение об ошибке правильное, но ведет вас в неверном направлении, говоря о реализации для AddAssign<f64>. В этом примере может быть полезно записать в журнал проблему , на тот случай, если команда компиляторов увидит способ исправить это.

...