Compiling playground v0.0.1 (/playground)
error[E0507]: cannot move out of `self` as enum variant `B` which is behind a shared reference
--> src/main.rs:24:15
|
24 | match self {
| ^^^^
25 | Enum::A(input, mut output) => {
| ---------- data moved here
...
28 | Enum::B(input, mut output) => {
| ---------- ...and here
|
= note: move occurs because these variables have types that don't implement the `Copy` trait
For more information about this error, try `rustc --explain E0507`.
error: could not compile `playground` due to previous error
The -> &Self return value still seems somewhat weird. Either remove it, or - if method chaining is wanted - return &mut Self.
For explanation as to why the Enum::A(input, output) works: This pattern matched against a &mut Enum instead of Enum will bind input and output to &mut Struct instead of Struct accordingly.
There is an equivalent but older (as in supported in Rust for a longer time; not actually outdated) way to write the same pattern in Rust that some people still prefer, which looks like &mut Enum::A(ref mut input, ref mut output)
where ref mut variable is the explicit way to create a &mut Struct variable instead of (trying to) move the Struct value itself.
I’m not recommending you to necessarily use these alternative syntaxes, but it can be useful to have seen them for developing a better understanding of how patterns operate and what exactly the kind of “magic” is that is involved in matching a &mut SomeEnum against a SomeEnum::Variant(variable, …) pattern.
But this makes all of the the things of the enum mutable. In reality i also want to do some shifting in those branches, which is not implemented for mutable things:
Even though it doesn't resemble with the original question 100% I reply here once more with an exended (striped down) example of what I want to achieve:
The error is still that I "cannot move out of self". Are you able to enlighten me once more?
I also have a feeling that wrapping vecs in structs to work with them is kind of un-ideomatic, maybe someone can comment on that as well?
It's perfectly fine to put any type in a struct. Your code compiles with &mut self.0. (you don't want the iterator impl for the vector by-value, you want to iterate by mutable reference.)
Don't worry about asking too many questions. Reasoning about what syntax will borrow or move what value or variable in what way is somewhat nontrivial, but I'm sure you'll quickly get a better feeling for what kind of approaches you can try from the answers to questions like these.
I also feel like some of these cases, e. g. the idea to add * dereferencing to make the shift operation work, or to try not only the already suggested &self.0 but perhaps also &mut self.0 are things that the compiler could suggest better / be more helpful with, i. e. I see room for improvement in diagnostics.