Home > Blockchain >  How to check if a value in a Vec is None?
How to check if a value in a Vec is None?

Time:12-03

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 a None 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).

  • Related