rust noob here. I'm happily coding along, but now hit a snag: my attempt to find an element of a vector of structs is cut short by an error message I find no workaround for. Can somebody explain to me what goes on here? I'm really at a loss.
struct CompoundSegment
{
relative_end: f64
}
fn main() {
let segments = vec![CompoundSegment{relative_end: 0.5}, CompoundSegment{relative_end: 1.0}];
let needle = 0.3;
let pos = segments.binary_search_by(
|segment| segment.relative_end.cmp(&needle));
println!("{:?}", pos);
}
Compiling playground v0.0.1 (/playground)
error[E0599]: no method named `cmp` found for type `f64` in the current scope
--> src/main.rs:10:44
|
10 | |segment| segment.relative_end.cmp(&needle));
| ^^^ method not found in `f64`
|
= note: the method `cmp` exists but the following trait bounds were not satisfied:
`f64: std::iter::Iterator`
which is required by `&mut f64: std::iter::Iterator`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0599`.
error: could not compile `playground`.
To learn more, run the command again with --verbose.
Amazing. I’ve encountered a few quirks of IEE754 before, but this one was new.
I wonder about the error I got. I obviously googled it (and explained it), but didn’t find this. Is this just something one has to know, or how can we derive the solution form the error?
The compiler's suggestion is leading the wrong way here, unfortunately. It's seemingly talking about Iterator::cmp and not Ord::cmp, and identifying which was meant isn't that clear-cut, when there are multiple traits with a method of the same name.
So indeed, we'd have to understand ourselves that Ord::cmp was not available, since the compiler didn't want to mention it in this case. The reason is that floats don't implement Ord, because of the comparison rules of NaN. I guess this is the sort of interesting thing you'll learn about floats once in Rust, and now you know.
By the way, the comparison operators <, <=, >, >= are assoicated with the PartialOrd trait, and floats implement that.
Those ask a related but fundamentally different question than Ord::cmp.
The latter asks "how exactly do the 2 arguments relate to one another?", the answer to which is one of less than, equal, or more than, all of which are encoded in the std::cmp::Ordering enum.
The former however, each ask a more specific question: "is argument 0 less than/less than or equal to/greater than/greater than or equal to argument 1?", the answer to which is 1 bit wide: either true or false.
Because they ask and answer a different question, their use cases are different too.