我正在try 为一个简单的 struct 自动"派生"比较功能,如下所示:

#[derive(PartialEq, Eq)]
struct Vec3 {
    x: f64,
    y: f64,
    z: f64,
}

然而,Rust 1.15.1抱怨:

error[E0277]: the trait bound `f64: std::cmp::Eq` is not satisfied
 --> src/main.rs:3:5
  |
3 |     x: f64,
  |     ^^^^^^ the trait `std::cmp::Eq` is not implemented for `f64`
  |
  = note: required by `std::cmp::AssertParamIsEq`

我应该怎么做才能在这里导出默认实现?

推荐答案

Rust故意不执行浮动类型的Eq.这reddit discussion条可能会进一步解释为什么,但是tl;dr.博士说,浮点数不是完全可以排序的,所以奇怪的边缘情况是不可避免的.

但是,如果您想将比较添加到 struct 中,可以派生PartialOrd.这将为您提供比较运算符和相等运算符的实现:

#[derive(PartialEq, PartialOrd)]
struct Vec3 {
    x: f64,
    y: f64,
    z: f64,
}

fn main() {
    let a = Vec3 { x: 1.0, y: 1.1, z: 1.0 };
    let b = Vec3 { x: 2.0, y: 2.0, z: 2.0 };

    println!("{}", a < b); //true
    println!("{}", a <= b); //true
    println!("{}", a == b); //false
}

PartialOrdPartialOrd之间只需要==Eq之间的差,而PartialOrdEq之间只需要==Eq之间的差.所以,就像浮动本身一样,在对 struct 的实例进行比较时,应该记住这一点.

Rust相关问答推荐

为什么迭代器上的`. map(...)`的返回类型如此复杂?

我怎样才能从一个Rust 的日期中go 掉3年?

如何使用字符串迭代器执行查找?

在Rust中赋值变量有运行时开销吗?

值为可变对象的不可变HashMap

在执行其他工作的同时,从共享裁判后面的VEC中删除重复项

Gtk4-rs:将监视器作为gdk::monitor获取,而不是作为glib::对象获取

如何向下转换到MyStruct并访问Arc Mutex MyStruct实现的方法?

借来的价值生命周期 不够长,不确定为什么它仍然是借来的

提取指向特征函数的原始指针

Rust 并行获取对 ndarray 的每个元素的可变引用

为什么我们有两种方法来包含 serde_derive?

Rust中是否可以在不复制的情况下从另一个不可变向量创建不可变向量?

发生移动是因为 `data` 的类型为 `Vec`,它没有实现 `Copy` 特性

在 FFI 的上下文中,未初始化是什么意思?

预期类型参数,发现不透明类型

隐式类型闭包的错误生命周期推断

为什么我可以在没有生命周期问题的情况下内联调用 iter 和 collect?

你能用 Rust 和 winapi 制作 Windows 桌面应用程序吗?

如何从 Rust 中不同类型的多个部分加入 Path?