-1

This is my singly linked list code have to implement pop from end and pop from front functions still, but I'm having difficulty in writing pop from end function

#![allow(warnings)]

#[derive(Clone)]
struct List {
    el: i32,
    next: Box<Option<List>>
}

impl List {
    fn new(val: i32) -> List {
        return List {
            el: val,
            next: Box::new(None)
        }
    }

    fn from(arr: &[i32]) -> List {
        let mut head = List::new(arr[0]);

        let mut current = &mut head;
        for &val in &arr[1..] {
            /* current.next = Box::new(Some(List::new(val)));
            current = (*current.next).as_mut().unwrap(); */
            current.append(val);
        }
        return head
    }

    fn append(&mut self, val: i32) {
        let mut current = self;
        while let Some(ref mut next_node) = *current.next {
            current = next_node;
        }
        current.next = Box::new(Some(List::new(val)));
    }

    fn prepend(&mut self, val:i32) {
        // std::mem::replace(dest, src): 
        //    Moves src into the referenced dest, returning the previous dest value
        let old_self = std::mem::replace(self, List::new(val));
        self.next = Box::new(Some(old_self));
    }
}

fn main() {
    let mut list = List::new(42);
    list.append(32);
    list.append(2321);
    list.append(2839);
    list.prepend(69);
    list.pop(); // 2839 // difficulty in implementing this
    println!("{}", list);

    let mut list = List::from(&[1, 2, 3]);
    list.prepend(0);
    println!("{}", list);
}

Should I use Rc and RefCell to implement a singly linked list? I'm a beginner, so please help. Thanks!

9
  • Please edit your question to add the minimal reproducible example that uses pop and the actual error message. Commented Jan 13 at 7:18
  • 2
    1. Don't use linked lists. 2. If you really must use a linked list, don't write it yourself. 3. If you still want to write a linked list, read Learning Rust With Entirely Too Many Linked Lists.
    – Jmb
    Commented Jan 13 at 7:34
  • You have removed too much code, this is not a minimal reproducible example. How can we help you without seeing enough of the whole picture? Commented Jan 13 at 11:59
  • 1
    The votes are no judgement of your person, it is a judgement of your question. In its current state, it is not helpful for others with a similar issue. Therefore, I'll keep my DV. Commented Jan 13 at 12:00
  • 1
    This site is not a forum, and by far not the only resource for beginners. In contrast to forums, it means to be "a library of detailed, high-quality answers to every question about programming." (From the introducing statement of the tour, which you took some months ago.) Commented Jan 13 at 13:45

1 Answer 1

1

Possible solution

    fn pop(&mut self) -> Option<List> {
        match &mut*self.next {
            // if self.next is None
            // that means that the list only have one element
            // and idk what's you desired behavior, but I just return None
            None => None,

            // we check the next element
            Some(n) => {
                if n.next.is_none() {
                    // if the next element is the terminal element
                    // we take the self.next
                    // that will change the current.next to None
                    self.next.take()
                }else{
                    // if the next element is not the terminal element
                    n.pop()
                }
            }
        }
    }
fn main() {
    let mut list = List::new(42);
    list.append(32);
    list.append(2321);
    list.append(2839);
    list.prepend(69);
    println!("{}", list);

    println!("{:?}", list.pop());
    println!("{}", list);

    let mut list = List::from(&[1, 2, 3]);
    list.prepend(0);
    println!("{}", list);

    println!("{:?}",list.pop());
    println!("{}", list);
}
Output
LinkedList([69, 42, 32, 2321, 2839])

Some(List { el: 2839, next: None })
LinkedList([69, 42, 32, 2321])

LinkedList([0, 1, 2, 3])

Some(List { el: 3, next: None })
LinkedList([0, 1, 2])
Remark
ref deref box

there is this pattern &*self.next

let x: Box<Option<List>> =     self.next; // illegal, you cannot move it out
let x: Option<List>      =   * self.next; // illegal, you cannot move it out
let x: &Option<List>     = & * self.next; // legal, you can borrow the value
derive debug

you can use #[derive(Debug)] to make debug easier, and don't need to implement Display all the time.

#[derive(Clone, Debug)]
struct List {
    el: i32,
    next: Box<Option<List>>
}
0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.