Rust 链表实现以及引用学习

137 阅读1分钟

难点:

  1. 如何在所有权变更的情况下获取节点的引用
  2. 获取引用之后如何对其值进行修改并确认内存中的值也同步修改

关键方法

as_mut() 说明:该方法创建一个结构体对象的可变引用,当这个引用可以对结构体对象进行数据修改

as_ref() 说明:该方法创建一个新的引用,相当于copy了一份引用。修改该引用时不会修改之前的结构体对象的数据

代码

type TNode = Option<Box<Node>>;

#[derive(Debug)]
struct Node {
    data: i32,
    next: TNode,
}

#[derive(Debug)]
struct TList {
    head: TNode,
}

impl TList {
    pub fn new() -> Self {
        TList { head: None }
    }

    pub fn push(&mut self, data: i32) {
        if self.head.is_none() {
            self.head = Some(Box::new(Node { data, next: None }));
            return;
        }
        let last_node = self.get_last();
        last_node.next = Some(Box::new(Node { data, next: None }));
    }

    pub fn get_last(&mut self) -> &mut Box<Node> {
        let mut first_node = self.head.as_mut().unwrap();
        loop {
            if first_node.next.is_none() {
                return first_node;
            } else {
                first_node = first_node.next.as_mut().unwrap();
            }
        }
    }

    pub fn pop(&mut self) {
        if self.head.is_none() {
            return;
        }
        let mut first_node = self.head.as_mut().unwrap();
        if first_node.next.is_none() {
            self.head.take();
            return;
        }
        loop {
            if first_node.next.as_mut().unwrap().next.is_none() {
                first_node.next = None;
                return;
            } else {
                first_node = first_node.next.as_mut().unwrap();
            }
        }
    }

    pub fn find(&self, data: i32) -> Option<&Box<Node>> {
        if self.head.is_none() {
            return None;
        }
        let mut node = self.head.as_ref().unwrap();
        loop {
            if node.data.eq(&data) {
                return Some(node);
            } else {
                if node.next.is_none() {
                    return None;
                } else {
                    node = node.next.as_ref().unwrap();
                }
            }
        }
    }

    pub fn print_list(&self) {
        let mut first_node = self.head.as_ref().unwrap();
        loop {
            if first_node.next.is_none() {
                println!("当前节点值: {}", first_node.data);
                return;
            } else {
                println!("当前节点值: {}", first_node.data);
                first_node = first_node.next.as_ref().unwrap();
            }
        }
    }
}

pub fn run() {
    let mut list = TList::new();
    list.push(1);
    list.push(2);
    list.push(3);
    list.push(4);
    println!("{:#?}\n", list.find(9));
    // list.print_list();
}

// 结果
TList {
    head: Some(
        Node {
            data: 1,
            next: Some(
                Node {
                    data: 2,
                    next: Some(
                        Node {
                            data: 3,
                            next: Some(
                                Node {
                                    data: 4,
                                    next: None,
                                },
                            ),
                        },
                    ),
                },
            ),
        },
    ),
}