diff --git a/week3/linked_list/src/linked_list.rs b/week3/linked_list/src/linked_list.rs index 7527a1d..61b0215 100644 --- a/week3/linked_list/src/linked_list.rs +++ b/week3/linked_list/src/linked_list.rs @@ -1,11 +1,13 @@ use std::fmt; use std::option::Option; +#[derive(Debug)] pub struct LinkedList { head: Option>>, size: usize, } +#[derive(Debug)] struct Node { value: T, next: Option>>, @@ -43,7 +45,9 @@ impl LinkedList { Some(node.value) } - + pub fn iter<'a>(&'a self) -> LinkedListIter<'a, T> { + LinkedListIter { item: &self.head } + } } @@ -110,3 +114,56 @@ impl PartialEq for LinkedList { } } +pub struct LinkedListIter<'a, T> { + item: &'a Option>>, +} + +impl<'a, T> Iterator for LinkedListIter<'a, T> { + type Item = &'a T; + fn next(&mut self) -> Option { + match self.item { + Some(node) => { + self.item = &node.next; + Some(&node.value) + }, + None => None, + } + } +} + +impl<'a, T> IntoIterator for &'a LinkedList { + type Item = &'a T; + type IntoIter = LinkedListIter<'a, T>; + fn into_iter(self) -> Self::IntoIter { + LinkedListIter {item: &self.head} + } +} + +pub struct IntoIter(LinkedList); + +impl Iterator for IntoIter { + type Item = T; + fn next(&mut self) -> Option { + self.0.pop_front() + } +} + +impl IntoIterator for LinkedList { + type Item = T; + type IntoIter = IntoIter; + fn into_iter(self) -> Self::IntoIter { + IntoIter(self) + } +} + +pub trait ComputeNorm { + fn compute_norm(&self) -> f64 { + 0.0 + } +} + +impl ComputeNorm for LinkedList { + fn compute_norm(&self) -> f64 { + self.iter().map(|x| {x * x}).sum::().sqrt() + } +} \ No newline at end of file diff --git a/week3/linked_list/src/main.rs b/week3/linked_list/src/main.rs index 981d23e..e8e6de3 100644 --- a/week3/linked_list/src/main.rs +++ b/week3/linked_list/src/main.rs @@ -1,12 +1,14 @@ use linked_list::LinkedList; + +use crate::linked_list::ComputeNorm; pub mod linked_list; fn main() { - let mut list: LinkedList = LinkedList::new(); + let mut list: LinkedList = LinkedList::new(); assert!(list.is_empty()); assert_eq!(list.get_size(), 0); for i in 1..12 { - list.push_front(i); + list.push_front(i.to_string()); } println!("{}", list); println!("list size: {}", list.get_size()); @@ -20,9 +22,24 @@ fn main() { list2.pop_front(); println!("list2.pop_front: {}", list2); println!("list == list2 ?= {}", list == list2); - + // If you implement iterator trait: - //for val in &list { - // println!("{}", val); - //} + for val in &list { + // reference iterator + print!("{} ", val); + } + println!(); + for val in list { + // consuming iterator + print!("{} ", val); + } + println!(); + // let mut error = list.into_iter(); + // list 's moved in the second loop, so it cannot be used again + // assert_eq!(Some(String::from("10")), error.next()); + let mut list: LinkedList = LinkedList::new(); + for i in 1..12 { + list.push_front(f64::from(i)); + } + println!("ComputeNorm for {:?} = {}", list, list.compute_norm()); }