generics - 无法从 rust 中的“T”中减去“T”
问题描述
我正在制作一个point
struct
包含 2 个值x
和y
一个line
struct
包含两个值first_point
,second_point
所有这些结构都是泛型类型,所以我想为Line
struct 创建一个成员方法,但它说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}
}
解决方案
要使像+
, -
, 和之类的运算符*
适用于一个类型(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}
}
注意两件事:我也有T
implement std::marker::Copy
,因为这样可以更容易地使用操作符特征。此外,您使用了该srqt()
功能。但是,此功能仅适用于特定类型f32
和f64
. 我只是删除了上面代码中的调用以使其编译为整数。正如@Ibraheem Ahmed 指出的那样,如果您真的需要这样的功能,那么num-traits crate 可以帮助您。
推荐阅读
- reactjs - 如何将 Material UI Temporary Drawer 按钮设置为图标而不是文本?
- google-apps-script - 如何为脚本添加延迟?
- python - django 中错误的 URL 配置/模式
- c++ - 在具有相同参数和兼容返回值的 C++ 方法指针之间进行转换
- python-3.x - 如何运行 while 循环来运行 REST API 调用,直到 Python 不再返回结果
- sql - 从另一个表中获取记录数
- jupyter-notebook - GPU/TPU 上的 PyCaret 方法
- ubuntu - 更改文件大小标签
- image-processing - 复制研究:开闭形态
- python - 大数除法导致结果不准确