moved arrays to it's own file
This commit is contained in:
@@ -0,0 +1,67 @@
|
|||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub struct EmptyListError;
|
||||||
|
|
||||||
|
// implementing Error for my error to satisfy Box<dyn std::error::Error>
|
||||||
|
// not needed ATM
|
||||||
|
// impl std::error::Error for EmptyListError {}
|
||||||
|
|
||||||
|
// so we can pass EmptyListError to println!
|
||||||
|
impl std::fmt::Display for EmptyListError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
write!(f, "Error: list must not be empty")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result<...,Box<dyn std::error::Error>> is overkill
|
||||||
|
// this is intuitive enough for caller error detection
|
||||||
|
// actually probably should use Option instead, but this is better for extension
|
||||||
|
pub fn min_and_max(list: &[u32]) -> Result<(u32, u32), EmptyListError> {
|
||||||
|
if list.is_empty() {
|
||||||
|
return Err(EmptyListError);
|
||||||
|
}
|
||||||
|
let mut min:u32 = 100;
|
||||||
|
let mut max:u32 = 0;
|
||||||
|
for i in list {
|
||||||
|
if *i > max {
|
||||||
|
max = *i;
|
||||||
|
}
|
||||||
|
if *i < min {
|
||||||
|
min = *i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok((min,max))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*; // need access to functions above
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_arrays() {
|
||||||
|
// empty array
|
||||||
|
let empty = [];
|
||||||
|
let empty_min_and_max = min_and_max(&empty);
|
||||||
|
assert!(empty_min_and_max.as_ref().is_err()); // as_ref() so we don't perform move
|
||||||
|
assert!(*(empty_min_and_max.as_ref().err().unwrap()) == EmptyListError);
|
||||||
|
println!("Expected: {}", *(empty_min_and_max.as_ref().err().unwrap()));
|
||||||
|
|
||||||
|
// array - contiguous, entirely on the stack, fixed at compile time, no pointer indirection
|
||||||
|
let l = [ 1, 2, 10, 100, 50, 75, 36, 21];
|
||||||
|
let l_min_and_max = min_and_max(&l);
|
||||||
|
assert!(l_min_and_max.as_ref().unwrap().0 == 1);
|
||||||
|
assert!(l_min_and_max.as_ref().unwrap().1 == 100);
|
||||||
|
|
||||||
|
// vec - stack: ptr, len, cap; ptr -> heap: contiguous allocation of capacity
|
||||||
|
// when variable goes out of scope drop() is called to deallocate the heap
|
||||||
|
let v = vec![1,2,3];
|
||||||
|
let v_min_and_max = min_and_max(&v);
|
||||||
|
assert!(v_min_and_max.as_ref().unwrap().0 == 1);
|
||||||
|
assert!(v_min_and_max.as_ref().unwrap().1 == 3);
|
||||||
|
|
||||||
|
let s = String::from("hello");
|
||||||
|
let r = &s;
|
||||||
|
println!("{}", *r); // works because there is no implicit move
|
||||||
|
// let thing = *r; // doesn't work because String does not implement Copy trait
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-10
@@ -1,4 +1,5 @@
|
|||||||
mod string;
|
mod string;
|
||||||
|
mod arrays;
|
||||||
mod fmt_debug;
|
mod fmt_debug;
|
||||||
|
|
||||||
// when a String is passed to this function a move occurs:
|
// when a String is passed to this function a move occurs:
|
||||||
@@ -112,14 +113,5 @@ fn main() {
|
|||||||
|
|
||||||
// todo: Cow
|
// todo: Cow
|
||||||
println!("Learning Rust");
|
println!("Learning Rust");
|
||||||
|
|
||||||
let empty = [];
|
|
||||||
let empty_min_and_max = min_and_max(&empty);
|
|
||||||
assert!(empty_min_and_max.as_ref().is_err());
|
|
||||||
assert!(*(empty_min_and_max.as_ref().err().unwrap()) == EmptyListError);
|
|
||||||
|
|
||||||
let l = [ 1, 2, 10, 100, 50, 75, 36, 21];
|
|
||||||
let l_min_and_max = min_and_max(&l);
|
|
||||||
assert!(l_min_and_max.as_ref().unwrap().0 == 1);
|
|
||||||
assert!(l_min_and_max.as_ref().unwrap().1 == 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user