Problem with match and enum Option<T>


#1

I am a new learner, and when I writing queue code like this:

#[derive(Debug)]
struct Queue<T> {
    qdata: Vec<T>,
}

impl <T> Queue<T> {
 
    fn pop(&mut self) {
        let val = Some(self.qdata);
        match val {
            None => println!("The Queue has no elements"),
            Some(x) => x.remove(0),
        }
    }
}

but match pattern has problem, compiling message is as follow:

src/lib.rs:24:9: 27:10 error: match arms have incompatible types:
expected (),
found T
(expected (),
found type parameter) [E0308]
src/lib.rs:24 match val {
src/lib.rs:25 None => println!(“The Queue has no elements”),
src/lib.rs:26 Some(x) => x.remove(0),
src/lib.rs:27 }
src/lib.rs:24:9: 27:10 help: run rustc --explain E0308 to see a detailed explanation
src/lib.rs:26:24: 26:35 note: match arm with an incompatible type
src/lib.rs:26 Some(x) => x.remove(0),
^~~~~~~~~~~
error: aborting due to previous error
Could not compile queue.

I don’t know why types don’t compatible?
Thanks in advance


#2

because println! returns no value and remove does.

But the code looks very suspicious to me:

  1. Why are you constructing an Option<Vec<T>> just destructure it again with match? That doesn’t make any sense, because the None branch will never be taken.
  2. The element that is popped is just discarded and never returned.

x will always be the same as qdata, so your code is actually equivalent to:

impl <T> Queue<T> {
    fn pop(&mut self) {
        self.qdata.remove(0);
    }
}

#3

Thanks, at first I tried like your suggestions, but it has a bug. When all of the elements of vector have been popped out, if continue to call method pop, it will break down, I have to detect this state, and I want to use Option to solve this problem.


#4

You cannot use Option in this case. Instead, you probably want to check the length of the vector before removing the element:

impl<T> Queue<T> {
    fn pop(&mut self) {
        if self.qdata.len() > 0 {
            self.qdata.remove(0);
        }
    }
}

#5

Thanks a lot. I have solved the problem like your code.

pub fn pop(&mut self) {
        if self.qdata.is_empty() {
            println!("The Queue has no elements");
        } else {
            self.qdata.remove(0);
        }

#6

I think you have misunderstood my comment.
I didn’t suggest a solution, I was merely pointing out that there is no difference at all between your code and the one that I’ve written.

You were wrapping the entire Vec and then immediately unwrapping it again, while checking if it is really there (which is obviously true).


#7

FYI, if you’re just looking to use a queue (i.e., making the queue wasn’t your goal), I highly recommend that you use a VecDeque as using a Vec this way will have O(n) runtime per pop (where n is the length of the queue).


#8

Sorry, I misunderstood your comment. I am not familiar with Option, and I’m learning to use it.
Tanks your comment.


#9

Tanks, I am learning algorithm and I try to make the queue. Later I found VecDeque in the std lib.