As a simple exercise to learn Rust, I've decided to implement a simple binary search:
pub fn binary_search(arr: &[i32], key: i32) -> usize {
let min: usize = 0;
let max: usize = arr.len();
while max >= min {
let mid: usize = (max - min) / 2 as usize;
if key == arr[mid] {
mid as usize
}
if key < arr[mid] {
min = mid + 1;
continue;
}
max = mid - 1;
}
-1 as usize
}
#[cfg(test)]
mod tests {
use super::binary_search;
#[test]
fn binary_search_works() {
let arr: [i32; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
let index: usize = binary_search(&arr, 2);
assert_eq!(1, index);
}
}
At build time, I get this error which I do not understand. What is the ()
type? Variable mid
is always usize
but even with the as
cast I'm getting this compilation error.
error: mismatched types [E0308]
mid as usize
^~~~~~~~~~~~
help: run `rustc --explain E0308` to see a detailed explanation
note: expected type `()`
note: found type `usize`
() is the unit type, analogous to a
void
return type in other languages.You're getting it here:
Rust is expecting that if expression to return
()
, but you're returningusize
for that expression. Since virtually everything in Rust is an expression, you can usually implicit return like you're trying to here, but in this specific case you can't because theif
expression is not the only expression in thewhile
expression. You could fix the immediate problem by usingreturn mid as usize;
instead.()
is the unit type or singleton type: it has a single value, also denoted()
.I personally view it as a tuple with 0 elements.
Where C or C++ would use
void
(which has no value) to indicate the return type of a function which returns nothing interesting, Rust uses()
instead. This is much nicer to meta-programming, as()
is a regular type which accepts values, can be mutated, borrowed, etc...Regarding your specific code sample:
is an expression of type
()
(because there is noelse
branch) yet you are attempting to have theif
block evaluate tomid as usize
which has the typeusize
thus the compiler notices the mismatch.You want to use a
return
here: