Reputation: 127
I've got this code snippet (playground link) where I'm basically trying to change a trait implementation to allow a state change for the struct it's applied to.
The current method signature is:
fn approve(self: Box<Self>) -> Box<dyn State>
, but I need to make it into something like
fn approve(&mut self: Box<Self>) -> Box<dyn State>
This doesn't compile. I've yet to see a Rust &mut self
parameter definition along with a type, though I'm not sure why that would be an issue.
If I try:
fn approve(&mut self) -> Box<dyn State>
I get other compile-time errors when I try to return an unmodified self
from the method.
For a little bit more context (before checking the playground), here are some relevant code bits:
trait State {
fn approve(self: Box<Self>) -> Box<dyn State>;
}
struct Draft {
approve_count: u8,
}
impl State for Draft {
fn approve(self: Box<Self>) -> Box<dyn State> {
// self.approve_count += 1;
if self.approve_count == 2 {
Box::new(Approved {})
} else {
self
}
}
}
struct Approved {}
impl State for Approved { ... }
What I would like to do is be able to uncomment the self.approve_count += 1;
line and have it work.
Upvotes: 1
Views: 582
Reputation: 155246
The correct syntax for a mutable reference is:
fn approve(self: &mut Box<Self>)
...but then you won't be able to return self
as Box<dyn State>
because you're only holding a reference to self.
If all you need is for self.approve_count += 1
to work, you don't need to switch to &mut self
, you can simply declare mut self: Box<Self>
:
impl State for Draft {
fn approve(mut self: Box<Self>) -> Box<dyn State> {
self.approve_count += 1;
if self.approve_count == 2 {
Box::new(Approved {})
} else {
self
}
}
...
}
That code is a bit suspect in that it modifies self.approved_count
even in the case where the function returns a completely new Approved
instance (and discards the just incremented value), but that may be fixed by moving the increment into the else
clause and adjusting the test as appropriate.
Upvotes: 3