■ Rc<T>/Weak<T> 구조체를 사용해 양방향 연결 리스트를 만드는 방법을 보여준다.
▶ double_linked_list.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
use std::cell; use std::rc; pub struct Node { data : isize, next : Option<rc::Rc<cell::RefCell<Node>>>, previous : Option<rc::Weak<cell::RefCell<Node>>> } pub struct DoubleLinkedList { head : Option<rc::Rc<cell::RefCell<Node>>>, foot : Option<rc::Rc<cell::RefCell<Node>>> } impl DoubleLinkedList { pub fn new() -> Self { return Self { head : None, foot : None}; } fn new_node(value : isize) -> rc::Rc<cell::RefCell<Node>> { let node_refcell : cell::RefCell<Node> = cell::RefCell::new(Node{ data : value, next : None, previous : None }); return rc::Rc::new(node_refcell); } pub fn push(&mut self, v : isize) { let node_refcell_rc : rc::Rc<cell::RefCell<Node>> = DoubleLinkedList::new_node(v); match self.foot.take() { None => { self.foot = Some(rc::Rc::clone(&node_refcell_rc)); self.head = Some(node_refcell_rc); }, Some(previous_foot_node_refcell_rc) => { self.foot = Some(rc::Rc::clone(&node_refcell_rc)); node_refcell_rc.borrow_mut().previous = Some(rc::Rc::downgrade(&previous_foot_node_refcell_rc)); previous_foot_node_refcell_rc.borrow_mut().next = Some(node_refcell_rc); } } } pub fn insert_head(&mut self, value : isize) { let new_node_refcell_rc : rc::Rc<cell::RefCell<Node>> = DoubleLinkedList::new_node(value); match self.head.take() { None => { self.foot = Some(rc::Rc::clone(&new_node_refcell_rc)); self.head = Some(new_node_refcell_rc); }, Some(previous_head_refcell_rc) => { previous_head_refcell_rc.borrow_mut().previous = Some(rc::Rc::downgrade(&new_node_refcell_rc)); new_node_refcell_rc.borrow_mut().next = Some(previous_head_refcell_rc); self.head = Some(new_node_refcell_rc); } } } pub fn iter(&mut self) -> ListIter { return match &self.head { None => ListIter { cur : None }, Some(head_refcell_rc) => { let head : rc::Rc<cell::RefCell<Node>> = rc::Rc::clone(&head_refcell_rc); ListIter { cur : Some(head) } }, }; } } pub struct ListIter { pub cur : Option<rc::Rc<cell::RefCell<Node>>> } impl Iterator for ListIter { type Item = isize; fn next(&mut self) -> Option<Self::Item> { match self.cur.take() { None => None, Some(current_node_refcell_rc) => { let node_ref : cell::Ref<'_, Node> = current_node_refcell_rc.borrow(); let data : isize = node_ref.data; match &node_ref.next { None => self.cur = None, Some(next) => self.cur = Some(rc::Rc::clone(&next)) }; return Some(data); } } } } |
▶ main.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
mod double_linked_list; fn main() { let mut list : double_linked_list::DoubleLinkedList = double_linked_list::DoubleLinkedList::new(); list.push(300); list.push(400); list.insert_head(100); list.insert_head(200); for value in list.iter() { println!("{}", value); } } |