-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. 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>>
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.