It contains an enum where at least one option holds a value. If I want to match that enum and change the value in the enum, I have to specify ref mut value and work on *value. Usually when I work with a reference in rust I use &mut value e.g. if a function borrows a reference to something. Is there a reason why in this case ref instead of & must be used?
Patterns's job is to destructure data. & value and &mut value are actually valid patterns, but they do the opposite of what you want in this case: they match references and bind value to the references value. Patterns Are Not Expressions is a great read to create an intuition for this.
ref mut value instead does match any value, but binds value to a reference to the matches value.
You should also consider doing match &mut foo (IMO the most common way to do this, ref is very rarely used). With this you will be able to use MyEnum::WithVal(value) as pattern, which thanks to match ergonomics will be the same as using &mut MyEnum::WithVal(ref mut value) as pattern.
Thanks for your reply.
I was not aware of the match &mut foo ..., which makes total sense. Thus, the confusion with ref.
I will read the patterns are not expressions you linked.
No, not really – ref is the original way to do this, the "new" way, "match ergonomics" is actually overgrown syntax sugar, and wouldn't even compile if it weren't for the special cases, as it's simply isn't type-correct.
(For this reason, I usually recommend ref, because then every type matches up correctly, and the code is very obvious to read.)
Who cares about 3 characters? Code quality is not a function of how terse you can possibly make everything.
Your example doesn't demonstrate that anyways. String literals already have type &str, so matching string literals with a &str is type-safe, whereas neither of your examples even compile (so they can't involve match ergonomics because they are simply not correct code).
Compiling playground v0.0.1 (/playground)
error[E0277]: the size for values of type `[u32]` cannot be known at compilation time
--> src/main.rs:10:17
|
10 | [first, rest @ ..] => println!("Many numbers: {first}, and {} others", rest.len()),
| ^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u32]`
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` (bin "playground") due to previous error
Of course matching on &nums would also be possible like previous commenters suggested, though for this case I do need to take the ownership