'How can I pattern match Option in rust? Current code keeps panicking

I am working on a simple binary search algorithm in rust. It returns an Option<usize> and I am trying to pattern match on the return value. My code currently fails on the None path. Its clear to me that I am not using the keyword correctly. Can anyone explain what I am doing wrong?

Code and output below.

Code:

fn find_index( arr: &[usize], find: usize) -> Option<usize> {
   let length = arr.len();
   let mut half = length / 2;
   let mut hind = length - 1;
   let mut lind = 0;
   let mut current = arr[half];

   while  lind <= hind {
       if current == find {
           return Some(half);
       }
       else if current < find{
           lind = half + 1;
       }
       else if current > find {
           hind = half - 1;
       }
        half = (hind + lind) / 2;
        current = arr[half];
   }
   return None;
}

fn grab_array_index(my_arr : &[usize], find: usize) -> usize{ 
    return my_arr.iter()
    .position(|&x| x == find)
    .unwrap();
}

fn main() 
{
    let mut arr = vec![1,2,3,4,5,6];
    let mut find = 3;

    println!("Index of {} is {}", find , grab_array_index(&arr, find));
    match find_index(&arr, find) {
        Some(p) => println!("Here ya go! {}", p),
        None => println!("not in the array >:("),
    }

    arr = vec![1,3,5,7,9,11,13,15,17,19];
    find = 17;

    println!("Index of {} is {}", find , grab_array_index(&arr, find));
    match find_index(&arr, find) {
        Some(p) => println!("Here ya go! {}", p),
        None => println!("not in the array >:("),
    }

    arr = vec![1,3,5,7,9,11,13,15,17,19];
    find = 18;

    println!("Index of {} is {}", find , grab_array_index(&arr, find));
    match find_index(&arr, find) {
        Some(p) => println!("Here ya go! {}", p),
        None => println!("not in the array >:("),
    }
}

Output:

Index of 3 is 2
Here ya go! 2
Index of 17 is 8
Here ya go! 8
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', binary_search.rs:27:6
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


Solution 1:[1]

It's panicking because before you call find_index(&arr, find) where find == 18, you call grab_array_index which has a call to unwrap in it. Since 18 is not in arr, grab_array_index panics on the unwrap. Consider having that function return an Option<usize> as well by removing the call to unwrap.

I'm assuming you're doing this for educational purposes, and as such I recommend checking out the source for std's binary search when you feel satisfied with your solution to see how they make use of language features to generalize the algorithm and make it more efficient.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ian S.