为了约束类型参数,为什么需要一个特征?
问题描述:
为什么在下面的代码中需要特质?没有特征的注释变体不会编译,即使它看起来好像具有相同的可用信息。为了约束类型参数,为什么需要一个特征?
trait ReliabilityConstructor<T> {
fn new(a: T) -> Reliability;
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
struct Reliability {
alpha: i8,
}
//impl<T> Reliability
impl<T> ReliabilityConstructor<T> for Reliability
where
f64: std::convert::From<T>,
{
fn new(a: T) -> Reliability {
let mut a_f64 = f64::from(a);
a_f64 = if a_f64 < -1f64 {
-1f64
} else if a_f64 > 1f64 {
1f64
} else {
a_f64
};
Reliability { alpha: (100f64 * a_f64) as i8 }
}
}
fn main() {
println!("{:?}", Reliability::new(-1));
}
答
刚刚从From
改变性状Into
(因为From<T> for U
意味着Into<U> for T
) - 其意图是多少更清晰:
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
struct Reliability {
alpha: i8,
}
impl Reliability {
fn new<T: Into<f64>>(a: T) -> Reliability { // <T> is only here
let mut a_f64: f64 = a.into(); // into() is used here
a_f64 = if a_f64 < -1f64 {
-1f64
} else if a_f64 > 1f64 {
1f64
} else {
a_f64
};
Reliability { alpha: (100f64 * a_f64) as i8 }
}
}
fn main() {
println!("{:?}", Reliability::new(-1));
}
答
那是因为你对特征定义,而不是结构定义中定义的类型参数。为了摆脱的特质,你需要移动T
到结构本身:
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
struct Reliability<T> {
alpha: i8,
}
impl<T> Reliability<T> where f64: std::convert::From<T> {
fn new(a: T) -> Reliability<T> {
let mut a_f64 = f64::from(a);
a_f64 = if a_f64 < -1f64 {
-1f64
} else if a_f64 > 1f64 {
1f64
} else {
a_f64
};
Reliability { alpha: (100f64 * a_f64) as i8 }
}
}
fn main() {
println!("{:?}", Reliability::new(-1));
}
那说,这就提出了一个不同的问题 - Reliability
在定义或实现任何地方实际上并未使用T
,使它会与此错误翻倒:
error[E0392]: parameter `T` is never used
--> <anon>:2:24
|
2 | struct Reliability<T> {
| ^unused type parameter
|
= help: consider removing `T` or using a marker such as `std::marker::PhantomData`
error: aborting due to previous error
编辑:写这个答案之后,我意识到自己的问题 - 你不是要限制的结构,你只是想约束的方法。在这种情况下,它更容易!
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
struct Reliability {
alpha: i8,
}
impl Reliability {
fn new<T>(a: T) -> Reliability where f64: std::convert::From<T> {
let mut a_f64 = f64::from(a);
a_f64 = if a_f64 < -1f64 {
-1f64
} else if a_f64 > 1f64 {
1f64
} else {
a_f64
};
Reliability { alpha: (100f64 * a_f64) as i8 }
}
}
fn main() {
println!("{:?}", Reliability::new(-1));
}
谢谢,这无疑变得更具可读性和摆脱的特质。我想这也意味着可靠性实施成,这是一个很好的触摸:) –