2015-01-16 2 views
0

Я пишу LoG-фильтр в Rust, и я хотел использовать | в качестве оператора оператора умножения элемента (a_{i,j} * b_{i,j}), но компилятор жалуется на результат Output. Он говорит, что self[(i, j)] * out[(i, j)] не равен Mul<N>::Output.Оператор для параметризованной структуры зависит от другого оператора

impl<N> BitOr<Matrix<N>> for Matrix<N> where N: Mul<N> { 
    type Output = Matrix<N>; 

    fn bitor(self, other: Matrix<N>) -> Matrix<N> { 
     if self.width() != other.width() || 
      self.height() != other.height() { 
       panic!("Matrices need to have equal dimensions"); 
      } 

     let mut out = Matrix::new(self.width(), self.height()); 

     for i in 0..(self.width()) { 
      for j in 0..(self.height()) { 
       out[(i, j)] = self[(i, j)] * out[(i, j)]; 
      } 
     } 

     out 
    } 
} 

Есть ли способ установить выход на основе Mul<N>::Output типа?

ответ

3

Я думаю, это должно работать:

impl<N> BitOr<Matrix<N>> for Matrix<N> where N: Mul<N> { 
    type Output = Matrix<<N as Mul<N>>::Output>; 

    fn bitor(self, other: Matrix<N>) -> Matrix<<N as Mul<N>>::Output> { 
     if self.width() != other.width() || 
      self.height() != other.height() { 
       panic!("Matrices need to have equal dimensions"); 
      } 

     let mut out = Matrix::new(self.width(), self.height()); 

     for i in 0..(self.width()) { 
      for j in 0..(self.height()) { 
       out[(i, j)] = self[(i, j)] * out[(i, j)]; 
      } 
     } 

     out 
    } 
} 
+0

Кстати, может быть, даже 'N :: Output' вместо' > :: Output' будет работать, но я не уверен здесь. –

1

Вы не предоставили небольшой работоспособный пример, так что я сделал сам. Это работает:

use std::ops::{Mul,BitOr}; 

#[derive(Copy,Show)] 
struct Matrix<N>(N, N); 

impl<N> BitOr<Matrix<N>> for Matrix<N> where N: Mul<N, Output=N> { 
    type Output = Matrix<N>; 

    fn bitor(self, other: Matrix<N>) -> Matrix<N> { 
     Matrix(self.0 * other.0, self.1 * other.1) 
    } 
} 

fn main() { 
    let a = Matrix(-1,-1); 
    let b = Matrix(2,3); 
    let c = a | b; 

    println!("{:?}", c) 
} 

Главное, что я должен был сделать N: Mul<N, Output=N>, который указывает, что N должен быть другой способный увеличиваться Nи приведет к другому N.

+1

FWIW, этот подход ограничивает реализацию только теми типами, операция умножения которых возвращает себя (т. Е. 'Output = N'). Это не всегда желательно. –

Смежные вопросы