최근 프로젝트 중 러스트를 사용할 일이 있어서 러스트를 학습 중이다.
대학교때 공부했던게 사용하지 않으니 머릿속에서 정말 말끔하게 증발해버렸다. (뭐 어딘가엔 어렴풋하게 있겠지만)
러스트 이중 연결리스트에 대한 코드다.
현재 학습 중인 자료에서 Rust double linked list코드가 나오는데 좋은 개념들이 함께 등장해서 분석해보면 좋을 것 같은 예제이다.
그나저나 lifetime은 아직도 긴가민가하다.
이런 syntax자체가 생소해서인지.
use std::cell::RefCell;
use std::rc::{Rc, Weak};
pub struct Node {
data: isize,
next: Option<Rc<RefCell<Node>>>,
prev: Option<Weak<RefCell<Node>>>,
}
pub struct List {
head: Option<Rc<RefCell<Node>>>,
foot: Option<Rc<RefCell<Node>>>,
}
impl List {
pub fn new() -> Self {
Self {
head: None,
foot: None,
}
}
fn new_node(v: isize) -> Rc<RefCell<Node>> {
Rc::new(RefCell::new(Node {
data: v,
next: None,
prev: None,
}))
}
pub fn push(&mut self, v: isize) {
let n = List::new_node(v);
match self.foot.take() {
None => {
self.foot = Some(Rc::clone(&n));
self.head = Some(n);
}
Some(old_foot) => {
self.foot = Some(Rc::clone(&n));
n.borrow_mut().prev = Some(Rc::downgrade(&old_foot));
old_foot.borrow_mut().next = Some(n);
}
}
}
pub fn unshift(&mut self, v: isize) {
let n = List::new_node(v);
match self.head.take() {
None => {
self.foot = Some(Rc::clone(&n));
self.head = Some(n);
}
Some(old_head) => {
old_head.borrow_mut().prev = Some(Rc::downgrade(&old_head));
n.borrow_mut().next = Some(old_head);
self.head = Some(n);
}
}
}
pub fn iter(&mut self) -> ListIter {
match &self.head {
None => ListIter { cur: None },
Some(head) => {
let head = Rc::clone(&head);
ListIter { cur: Some(head) }
}
}
}
}
pub struct ListIter {
pub cur: Option<Rc<RefCell<Node>>>,
}
impl Iterator for ListIter {
type Item = isize;
fn next(&mut self) -> Option<Self::Item> {
match self.cur.take() {
None => None,
Some(cur) => {
let cb = cur.borrow();
let data = cb.data;
match &cb.next {
None => self.cur = None,
Some(next) => self.cur = Some(Rc::clone(&next)),
}
Some(data)
}
}
}
}
반응형
'Rust' 카테고리의 다른 글
[Rust] Rust가 ++연산자를 지원하지 않는 이유 (0) | 2024.05.03 |
---|---|
[WASM] 웹 어셈블리의 미래 - WebAssembly (0) | 2022.01.26 |
[Rust] 러스트를 배워봅시다! - Rust language 간단 후기1 - 재밌다! (0) | 2022.01.15 |
[Rust] 러스트를 배워봅시다. (0) | 2022.01.12 |