I'm trying to only print the first element of the vector if it contains something:
let mut optional_integers_vec: Vec<Option<i8>> = Vec::new();
match optional_integers_vec[0].unwrap() {
Err(e) => println!("Nothing in the first element currently"),
Ok(_) => println!("Vec contains in first element {}",optional_integers_vec[0].unwrap() ),
}
This produces the following error:
Err(e) ^^^^^^ expected i8, found enum Result
Ok(_) ^^^^^ expected i8, found enum Result
Option::unwrap() is primarily useful when you're certain that the value is Some, since it's an assertion that throws a panic on failure. To test whether or not the value is Some, you can match on it directly (Rust Playground):
let optional_integers_vec: Vec<Option<i8>> = vec![Some(42)];
match optional_integers_vec[0] {
None => println!("Nothing in the first element currently"),
Some(v) => println!("Vec contains in first element {v}"),
}
(Note that this will panic if optional_integers_vec is empty.)
optional_integers_vec.iter().nth(0).map(|maybe_first_element| {
match maybe_first_element {
Some(first_element) => {
println!("first element was {first_element}")
}
None => println!("first element was None")
}
}
let mut optional_integers_vec: Vec<Option<i8>> = Vec::new();
match &*optional_integers_vec {
[] => println!("empty Vec"),
[None, ..] => println!("Nothing in the first element currently"),
[Some(elt), ..] => println!("Vec contains in first element {elt}" ),
}
This doesn't panic, clearly enumerates the possible cases, and doesn't require manually digging into the Vec and its elements since pattern matching does it for you.
I ended up putting it into a function like this, NB the compiler didn't like match veccy and suggested match veccy[..]:
fn first_el_print(veccy : &Vec<Option<i8>>){
match veccy[..]{
[] => println!("Vec is empty"),
[None, ..] => println!("Nothing in first element"),
[Some(elem), ..] => println!("Vec contains something in 1st element which is {}",elem),
}
}
That gets called like this:
let mut optional_integers_vec: Vec<Option<i8>> = Vec::new();
first_el_print(&optional_integers_vec);
I'm pretty new to Rust, I would like to ask about where you used the address and the dereference together &*, I'm confused by that and haven't seen it before, is it a way of making certain that you get the address of the actual datastructure rather than say of its pointer?:
That's why you needed [..]. In case of Vec, these are two ways to convert it into borrowed slice: one is using Deref coercion (&*v first converts Vec<T> to [T] via dereference and then give back the &[T]), another - Index operator.
Note that you shouldn't accept a &Vec as a function parameter. It is useless (an immutable vector doesn't have more API than a slice), and can actually hurt performance, because it forces the caller to have an actual owned vector, instead of just a slice. So if someone has, say, a stack-allocated array, which would deref to a slice just fine, you will force them to copy the array into a heap-allocated vector. Just accept a slice instead.