简体   繁体   中英

cannot subtract `T` from `T` in rust

I'm making a point struct containing 2 values x and y and a line struct containing two values first_point and second_point all these structs are generic type so I wanted to make a member method for Line struct but it's saying cannot subtract `T` from `T`

impl<T> Line<T> {

    fn len(&self) -> T {
        let x = (self.second_point.x) - (self.first_point.x) ;
        let y = (self.second_point.y) - (self.first_point.y) ;
        return ((x * x) + (y * y)).sqrt() ;
    }
}

This is the error by the ways:

error[E0369]: cannot subtract `T` from `T`
  --> src/sources.rs:19:39
   |
19 |         let x = (self.second_point.x) - (self.first_point.x) ;
   |                 --------------------- ^ -------------------- T
   |                 |
   |                 T
   |
help: consider restricting type parameter `T`
   |
16 | impl<T: std::ops::Sub<Output = T>> Line<T> {
   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0369]: cannot subtract `T` from `T`
  --> src/sources.rs:20:39
   |
20 |         let y = (self.second_point.y) - (self.first_point.y) ;
   |                 --------------------- ^ -------------------- T
   |                 |
   |                 T
   |
help: consider restricting type parameter `T`
   |
16 | impl<T: std::ops::Sub<Output = T>> Line<T> {
   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0369`.

I'm a beginner in Rust so I would really appreciate it if you can help me with this:

And this is the full code if you are interested

pub fn test_function() {
    
    let line = make_a_line(make_a_point(10, 20),  make_a_point(10, 20));
    
}
struct Point<T> {
    x:T,
    y:T
}

struct Line<T> {
    first_point: Point<T>,
    second_point: Point<T>,
} 

impl<T> Line<T> {

    fn len(&self) -> T {
        let x = (self.second_point.x) - (self.first_point.x) ;
        let y = (self.second_point.y) - (self.first_point.y) ;
        return ((x * x) + (y * y)).sqrt() ;
    }
}

fn make_a_point<T>(x_axix:T, y_axis:T) -> Point<T>{
    Point{x: x_axix, y: y_axis}
}

fn make_a_line<T>(start: Point<T>, end: Point<T>) -> Line<T> {
    Line{first_point: start, second_point: end} 
}

To make operators like + , - , and * work for a type ( T in this case), the operator-specific std traits must be implemented for it: std::ops::Add , std::ops::Sub , std::ops::Mul . T must then be constrained, such that it implements them. Correcting your code for this could look like this:

pub fn test_function() {
    
    let line = make_a_line(make_a_point(10, 20),  make_a_point(10, 20));
    
}
struct Point<T>
    where T: std::marker::Copy + std::ops::Sub<Output=T> + std::ops::Mul<Output=T> + std::ops::Add<Output=T>,
{
    x:T,
    y:T
}

struct Line<T>
    where T: std::marker::Copy + std::ops::Sub<Output=T> + std::ops::Mul<Output=T> + std::ops::Add<Output=T>,
{
    first_point: Point<T>,
    second_point: Point<T>,
} 

impl<T> Line<T>
    where T: std::marker::Copy + std::ops::Sub<Output=T> + std::ops::Mul<Output=T> + std::ops::Add<Output=T>,
{

    fn len(&self) -> T {
        let x = (self.second_point.x) - (self.first_point.x) ;
        let y = (self.second_point.y) - (self.first_point.y) ;
        return ((x * x) + (y * y)) ;
    }
}

fn make_a_point<T>(x_axix:T, y_axis:T) -> Point<T>
    where T: std::marker::Copy + std::ops::Sub<Output=T> + std::ops::Mul<Output=T> + std::ops::Add<Output=T>,
{
    Point{x: x_axix, y: y_axis}
}

fn make_a_line<T>(start: Point<T>, end: Point<T>) -> Line<T>
    where T: std::marker::Copy + std::ops::Sub<Output=T> + std::ops::Mul<Output=T> + std::ops::Add<Output=T>,
{
    Line{first_point: start, second_point: end} 
}

Notice 2 things: I also have T implement std::marker::Copy , as that makes it easier to work with the operator traits. Additionally, you used the srqt() function. However this function is only available for the specific types f32 and f64 . I simply removed the call in the above code to make it compile for integers. If you really need such a function maybe the num-traits crate can help you out, as @Ibraheem Ahmed pointed out.

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