简体   繁体   中英

How can I return a generic type from a member function in Rust

I'm trying to write a generic matrix class in Rust. I'd like to have a get member function that returns a copy of the element at a given index in the matrix. The code currently looks like this:

mod math {
    pub struct Matrix<T> {
        rows: usize,
        columns: usize,
        data: Vec<T>,
    }

    impl<T> Matrix<T> where T: Copy {
        pub fn empty(rows: usize, columns: usize) -> Matrix<T> {
            return Matrix {
                rows: rows,
                columns: columns,
                data: Vec::with_capacity(rows * columns),
            };
        }

        pub fn get(&self, row: usize, column: usize) -> T {
            return self.data[column + row * self.columns];
        }
    }

    impl<T> PartialEq for Matrix<T>
    where
        T: PartialEq,
    {
        fn eq(&self, other: &Self) -> bool {
            if self.rows != other.rows || self.columns != other.columns {
                return true;
            }

            for i in 0..self.rows {
                for j in 0..self.columns {
                    if self.get(i, j) != other.get(i, j) {
                        return false;
                    }
                }
            }

            return true;
        }
    }
}

I get the following error from the Rust compiler (version 1.39.0):

error[E0599]: no method named `get` found for type `&math::Matrix<T>` in the current scope
  --> <source>:33:29
   |
33 |                     if self.get(i, j) != other.get(i, j) {
   |                             ^^^ method not found in `&math::Matrix<T>`
   |
   = note: the method `get` exists but the following trait bounds were not satisfied:
           `T : std::marker::Copy`
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following traits define an item `get`, perhaps you need to implement one of them:
           candidate #1: `core::panic::BoxMeUp`
           candidate #2: `std::slice::SliceIndex`

I'm struggling to understand what this error means. Is there some additional trait I need to use to constrain the T type?

In eq , self is a Matrix<T> where T: PartialEq as that's the bound for the impl where eq is defined. Calling get on it requires it's a Matrix<T> where T: Copy as that's the bound on the impl where get is defined. This is what the error message means:

the method get exists but the following trait bounds were not satisfied: T: std::marker::Copy

A type bound on one impl doesn't automatically get carried on to other impls.

You could fix this with

    impl<T> PartialEq for Matrix<T>
    where
        T: PartialEq + Copy

Or if you don't want to require this, you could return an &T from get and drop the where T: Copy

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM