I would like to use the fact that Vec.last()
returns a None
if there is nothing at that index but that index still exists. The problem is that I can't find a way to compare the result to anything inside of a while
or if
. I can however compare it if I use match
, although that seems less efficient than using a while
loop. Is there a way to compare it in an if
or a while
loop?
This is what I'm trying to do, but the self.particles.last() == None
is invalid since you can't compare things to None
except None
as far as I can tell.
while vec.last() == None {
num = 1;
}
CodePudding user response:
I would use Option::is_none
:
while vec.last().is_none() {
...
}
But that's boring. We're here to learn. Perhaps there's a convoluted, hard to read option where we can flex our Rust muscles? As it happens, there is! Let's take a look at one of my favorite Rust features, pattern matching.
What's that? Well, normally you'd write something like this, which loops as long we you get Some
items and simultaneously binds the items to a variable:
while let Some(elem) = vec.last() {
...
}
Some(elem)
is a pattern. It turns out that None
fills the same syntactical role. It's a pattern, albeit one without a variable:
while let None = vec.last() {
...
}
I admit let
without a variable looks odd, and it looks like it's backwards having the None
on the left, but it works.
(Also, I should point out this will be an infinite loop if you don't modify vec
.)
CodePudding user response:
I would like to use the fact that
Vec.last()
returns aNone
if there is nothing at that index but that index still exists.
You seem to be very confused about the behaviour of Vec::last
. It's absolutely not going to return None
if "that index still exists" (whatever that means). It's going to return None
if the vec is empty, that's it.
So your loop is either never going to execute, or will loop forever.
This is what I'm trying to do, but the self.particles.last() == None is invalid since you can't compare things to None except None as far as I can tell.
while vec.last() == None { num = 1; }
No? The issue would probably be that Option<T>
is PartialEq
iff T
is PartialEq
: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=00f4ea97a0fad1cd74ef3b6ac6b74dc8
#[derive(PartialEq, Eq)]
struct Equatable;
struct NonEquatable;
fn main() {
// compiles fine
println!("{}", None == Some(Equatable));
// can't compile
// println!("{}", None == Some(NonEquatable));
}
Though it is obviously not the normal way to do it, you'd usually use Option::is_none
, possibly matches!
in some rare cases (but that's more for enums which don't have predicates).