Returning Option from function

New rust user. I want to return a Vector from a function, or nothing. I want to check if there is a value, if not then do something else. The code below shows what I'm trying to accomplish, but it doesn't work.

fn main ()
{
    let mut pass_vector: Vec<i32>;
    for a in 1..100
    {
        pass_vector.push(a);
    }

    let mut result = match is_inside(2,300,&mut pass_vector) 
    {
        result => result,
        None => {
            panic!("Houston we have a problem.")
        },
    };

}


pub fn is_inside (a: i32, b:i32, passed_vectors: &mut Vec<i32> ) -> Option<Vec<i32>>
{
    let mut ret_val:  Vec<i32>;
    for x in passed_vectors
    {
        if a == *x
        {
            ret_val.push(a);
        }
        if b == *x
        {
            ret_val.push(b);
        }
    }
    if ret_val.len() == 0
    {
        return None;
    }
    else
    {
       return ret_val;
    }
}

You need to return Some(ret_val). What did the error message say?

Perfect! That explains the syntax. I was having problems understanding how to use the Option keyword. Now I can use this example (with the addition of the Some keyword) to do what I need.

Note that neither Option nor Some are keywords in the language. The Option type is a perfectly ordinary Rust type, which has two constructors Some and None.

The Option<T> has its own document like any other types defined in stdlib. You can see that it's just an enum type with exactly two variants - Some(T) and None.

Where do I put the missing Brackets? Compiler complains about this construct.

    let path: Vec<i32> = match crate::Sector::find_path_to_sector(445, 2, &mut read_sector_vector)
    {
        Some(path) => path,
        _ => (),
        },
    };
} // this bracket should be here, but compiler complains because the match section seems to be missing an opening bracket. 

I recommend trying to count how many open and close curly brackets you have.

Yes, there is a missing bracket in the match construct. But, when I try to use the exact same construct as in my example:

    {
        Some(result) => result,
        None => {
            ()
        },
    };

it will not compile, removing the bracket removes the error, but introduces another.

The () gives; expected struct std::vec::Vec, found ()

But in the example it works. Both real code and example return the same value "-> Option<Vec>"

I cannot find a decent explanation of how to check if a function is returning None or a Value and then have a decision point. Perhaps I'm doing everything wrong because I'm thinking in terms of C code.

if (some_function() != NULL) 

This is basically what I want to do, if the function returns nothing do one thing, if it has a value do another. I just cannot seem to wrap my brain around how to do this seemly simple action. I thought using "match" would allow me to do something like != NULL, but it seems to have introduced more problems than it solves.

So perhaps I'm asking the wrong question. The real question is how do I get a function to return a value or null and check do an IF/ELSE based on that evaluation?

You have this construct:

let path: Vec<i32> = match something {
    Some(result) => result,
    None => (),
};

You have something of type Option<Vec<i32>>, and the match expression should produce a value of type Vec<i32>. Now the match has two cases, and in the first case, result is indeed a vector of that type, so all is good. However () is not a vector, so if something happened to be None, you tried to assign () to a value of type vector. This doesn't make sense.

Note that the type Vec<i32> cannot be null, None, or anything of that sort.

I can only guess to what you want, but here are some snippets you may like:

if let Some(result) = something {
    // ... use result here
}

or perhaps

match something {
    Some(result) => {
        // use result here
    }
    None => {
        // oops, it was none
    }
}
1 Like

OK, I think I get it now. It seems like I want to use

if let Some(result) = something

not the match construct, since I really don't care if the result is null, I just need to know if it is before I attempt to use the results for something else. That makes a lot more sense in terms of what I'm doing now, and it is a good explanation of what I need in future if I use the match construct.

Thanks for all the help!