为带约束的结构实现 From/Into
Implementing From/Into for struct with constraints
由于 .max()
对 f64
不起作用,我正在编写一个 ForceOrd
结构来断言参数不是 NaN
。预期用途类似于:
let m = xs.iter().map(|&x| ForceOrd(x)).max().unwrap().into();
但是,我无法得到 Into
trait 实现来编译错误:
conflicting implementations of trait `std::convert::Into<_>` for type `ForceOrd<_>`
代码(playground):
#[derive(PartialEq, PartialOrd)]
pub struct ForceOrd<X: PartialEq + PartialOrd>(pub X);
impl<X: PartialEq + PartialOrd> Eq for ForceOrd<X> { }
impl<X: PartialEq + PartialOrd> Ord for ForceOrd<X> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.0.partial_cmp(&other.0).unwrap()
}
}
/// doesn't work
impl<X: PartialEq + PartialOrd> Into<X> for ForceOrd<X> {
fn into(x: Self) -> X { x.0 }
}
/// doesn't work either
impl<X: PartialEq + PartialOrd> From<ForceOrd<X>> for X {
fn from(x: ForceOrd<X>) -> Self { x.0 }
}
您不能为单一类型同时实现 From
和 Into
,即如果您还 impl Into<X> for ForceOrd<X>
,则不能 impl From<ForceOrd<X>> for X
。你也只需要一个。作为 Into
and From
的文档,两者都声明:
From<T> for U implies Into<U> for T
您可能应该只使用 From
实现。您可以查看以下问题以获取有关一般选择的信息:
Edit:因为实施 From
并不(在这种情况下)像删除 impl Into
一样微不足道,您可以在下面看到它是如何实现的达到 f64
:
#[derive(PartialEq, PartialOrd, Debug)]
pub struct ForceOrd<X: PartialEq + PartialOrd>(pub X);
impl<X: PartialEq + PartialOrd> Eq for ForceOrd<X> { }
impl<X: PartialEq + PartialOrd> Ord for ForceOrd<X> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.0.partial_cmp(&other.0).unwrap()
}
}
impl<X: PartialEq + PartialOrd> From<X> for ForceOrd<X> {
fn from(x: X) -> ForceOrd<X> {
ForceOrd(x)
}
}
fn main() {
let xs = vec![1.1f64, 3.5, 2.2];
let max = xs.iter().map(|&f| <ForceOrd<f64>>::from(f)).max().unwrap();
println!("{:?}", max); // prints "ForceOrd(3.5)"
}
不幸的是,恐怕这就是您所能得到的;你将无法实施:
impl<X: PartialEq + PartialOrd> From<ForceOrd<X>> for X
能够参加决赛
<f64>::from(xs.iter().map(|&f| <ForceOrd<f64>>::from(f)).max().unwrap())
因为 f64
不是这个 crate 的本地文件。您可以在 this very detailed blog entry by Niko Matsakis and see .
中阅读有关此限制的更多信息
由于 .max()
对 f64
不起作用,我正在编写一个 ForceOrd
结构来断言参数不是 NaN
。预期用途类似于:
let m = xs.iter().map(|&x| ForceOrd(x)).max().unwrap().into();
但是,我无法得到 Into
trait 实现来编译错误:
conflicting implementations of trait `std::convert::Into<_>` for type `ForceOrd<_>`
代码(playground):
#[derive(PartialEq, PartialOrd)]
pub struct ForceOrd<X: PartialEq + PartialOrd>(pub X);
impl<X: PartialEq + PartialOrd> Eq for ForceOrd<X> { }
impl<X: PartialEq + PartialOrd> Ord for ForceOrd<X> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.0.partial_cmp(&other.0).unwrap()
}
}
/// doesn't work
impl<X: PartialEq + PartialOrd> Into<X> for ForceOrd<X> {
fn into(x: Self) -> X { x.0 }
}
/// doesn't work either
impl<X: PartialEq + PartialOrd> From<ForceOrd<X>> for X {
fn from(x: ForceOrd<X>) -> Self { x.0 }
}
您不能为单一类型同时实现 From
和 Into
,即如果您还 impl Into<X> for ForceOrd<X>
,则不能 impl From<ForceOrd<X>> for X
。你也只需要一个。作为 Into
and From
的文档,两者都声明:
From<T> for U implies Into<U> for T
您可能应该只使用 From
实现。您可以查看以下问题以获取有关一般选择的信息:
Edit:因为实施 From
并不(在这种情况下)像删除 impl Into
一样微不足道,您可以在下面看到它是如何实现的达到 f64
:
#[derive(PartialEq, PartialOrd, Debug)]
pub struct ForceOrd<X: PartialEq + PartialOrd>(pub X);
impl<X: PartialEq + PartialOrd> Eq for ForceOrd<X> { }
impl<X: PartialEq + PartialOrd> Ord for ForceOrd<X> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.0.partial_cmp(&other.0).unwrap()
}
}
impl<X: PartialEq + PartialOrd> From<X> for ForceOrd<X> {
fn from(x: X) -> ForceOrd<X> {
ForceOrd(x)
}
}
fn main() {
let xs = vec![1.1f64, 3.5, 2.2];
let max = xs.iter().map(|&f| <ForceOrd<f64>>::from(f)).max().unwrap();
println!("{:?}", max); // prints "ForceOrd(3.5)"
}
不幸的是,恐怕这就是您所能得到的;你将无法实施:
impl<X: PartialEq + PartialOrd> From<ForceOrd<X>> for X
能够参加决赛
<f64>::from(xs.iter().map(|&f| <ForceOrd<f64>>::from(f)).max().unwrap())
因为 f64
不是这个 crate 的本地文件。您可以在 this very detailed blog entry by Niko Matsakis and see