我有像这样定义的结构
trait Calculate<T: Mul<Output = T>> {
fn calc(&self, Shape: T) -> T;
}
impl<T> Calculate<T> for Shape<T> {
fn calc(&self, Shape: T) -> T {
self.line_one * 2 + self.line_two * 2
}
}
impl Calculate<i32> {
fn calc(&self) -> i32 {
self.line_one * 2 + self.line_two * 2
}
}
fn calc_fn<T: Calculate<i32>>(calculate: T) {
calculate.calc();
}
我正在尝试创建一个简单的特征和实现,它使用这个结构来计算一些简单的数学。
我的特质和动作看起来像这样
Mul
当我将它放入Rust游乐场时,编译失败,因为impl Calculate<T>
中未实现<T>
。但是,如果我将<T: Mul<Output = T>>
更改为<anon>:14:21: 14:22 error: expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `:`
<anon>:14 impl <T> Calculate<T: Mul<Output = T>> for Shape<T>
,则会收到错误
Mul
我对T
中impl Calculate<T>
的{{1}}实施f32
感到茫然。
我想要实现的是我可以发送i32
或T
的代码而无需创建两个不同的impl定义,因此可以传入{{1}}
答案 0 :(得分:1)
此语法不正确:
impl<T> Calculate<T: Mul<Output = T>> for Shape<T>
你想要
impl<T: Mul<Output = T>> Calculate<T> for Shape<T>
我几乎总是建议使用where
子句;我认为它看起来更好,可能有助于防止这种情况:
impl<T> Calculate<T> for Shape<T>
where T: Mul<Output = T>,
这只会解锁更多错误。您正试图乘以2
,这是一个尚未完全确定的整数变量 - 它是u8
吗?它是i32
吗?限制并不表示T
可以乘以2
。此外,您尝试将值添加到一起,但无法保证您可以添加T
类型。
impl Calculate<i32>
和calc_fn
块并不真正有意义;你不太可能想implement functions for the trait而你不能在后者中提供Shape
。该特征也没有使用Shape: T
参数(而且Rust使用snake_case
变量名称。
我想要实现的是我可以发送
f32
或i32
的代码而无需创建两个不同的impl定义,因此可以传入T
在这种情况下,它可能会更容易:
trait Calculate<T> {
fn calc(&self) -> T;
}
impl Calculate<i32> for Shape<i32> {
fn calc(&self) -> i32 {
self.line_one * 2 + self.line_two * 2
}
}
impl Calculate<f32> for Shape<f32> {
fn calc(&self) -> f32 {
self.line_one * 2.0 + self.line_two * 2.0
}
}
请注意,这些不等效! f64
的浮点文字(2.0
)不是整数(2
)。
如果必须具有泛型,则需要将文字2
转换为类型T
或添加T可以乘以某些限制的限制已知尺寸。不幸的是,f64
不能在没有强制转换的情况下乘以任何整数值。
来自数字的FromPrimitive
特征是关键所在。使类型Copy
也使实现更容易。
extern crate num;
use std::ops::{Add, Mul};
use num::FromPrimitive;
struct Shape<T> {
line_one: T,
line_two: T,
}
trait Calculate<T> {
fn calc(&self) -> T;
}
impl<T> Calculate<T> for Shape<T>
where T: Copy + FromPrimitive + Add<Output = T> + Mul<Output = T>,
{
fn calc(&self) -> T {
let two = T::from_u8(2).expect("Unable to create a value of two");
self.line_one * two + self.line_two * two
}
}
fn main() {
let s1 = Shape { line_one: 2, line_two: 3 };
let s2 = Shape { line_one: 2.0, line_two: 3.0 };
println!("{}", s1.calc());
println!("{}", s2.calc());
}