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.