why do we need to call take() for Option<T> variable

If you code like this:

pub struct Post {
    state: Box<dyn State>,
    content: String,
}

trait State {
    fn request_review(self: Box<Self>) -> Box<dyn State>; 
}

impl Post {
    // ... 
    pub fn request_review(&mut self) {
        self.state = self.state.request_review();
    }
    // ... 
}

You will get a compiler error:

self.state = self.state.request_review();
             ^^^^^^ move occurs because `self.state` has type `std::boxed::Box<dyn State>`, which does not implement the `Copy` trait'.

This is because calling State::request_review will move Box<self>, which is allocated on heap, and Rust doesn't allow you to just move values away from heap unless you implement Copy, otherwise what's left there? The book uses Option::take() to move ownership out and leave None on the place.

Tags:

Rust