首页 > 解决方案 > 无法从 rust 中的“T”中减去“T”

问题描述

我正在制作一个point struct包含 2 个值xy一个line struct包含两个值first_pointsecond_point所有这些结构都是泛型类型,所以我想为Linestruct 创建一个成员方法,但它说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() ;
    }
}

这是错误的方式:

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`.

我是 Rust 的初学者,所以如果你能帮助我,我将不胜感激:

如果您有兴趣,这是完整的代码

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} 
}

标签: genericsrust

解决方案


要使像+, -, 和之类的运算符*适用于一个类型(T在这种情况下),std必须为其实现特定于运算符的特征:std::ops::Add, std::ops::Sub, std::ops::Mul. T然后必须受到约束,以便它实现它们。为此更正您的代码可能如下所示:

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} 
}

注意两件事:我也有Timplement std::marker::Copy,因为这样可以更容易地使用操作符特征。此外,您使用了该srqt()功能。但是,此功能仅适用于特定类型f32f64. 我只是删除了上面代码中的调用以使其编译为整数。正如@Ibraheem Ahmed 指出的那样,如果您真的需要这样的功能,那么num-traits crate 可以帮助您。


推荐阅读