Reputation: 3233
Consider the following snippet:
use std::fmt;
enum TestEnum {
StructMem {value: i32, is_valid: bool},
RandoMem,
}
impl fmt::Display for TestEnum {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use TestEnum::*;
match self {
StructMem {value, is_valid} => {
if *is_valid { // Why dereference is_valid ?
write!(f, "f")?
}
write!(f, "{:?}", value)
}
RandoMem => {
f.write_str("Random")
}
}
}
}
Why do I need to dereference is_valid
in the if
statement?
EDIT: This question What is the syntax to match on a reference to an enum? seems to be dealing with a similar situation, but the answers are all focused on solving the specific issue (which does not involve a struct) and are not explaining the ownership/binding semantics.
Upvotes: 0
Views: 603
Reputation: 15115
When you pattern match a reference and de-structure it you can only get references of the inner members, otherwise you'd be moving the inner members out of an immutable reference which would violate Rust's ownership rules. Here's a simpler example:
struct Container(Vec<i32>);
fn get_inner_vec(c: &Container) -> &Vec<i32> {
// v MUST BE a reference
// otherwise this destructing would somehow be moving the Vec
// outside of an immutable borrow of Container
let Container(v) = c;
v
}
Upvotes: 1
Reputation: 16475
This is not specific to the match
or the enum
but due to the signature of fmt()
, which takes self
as a reference (&self
instead of self
, if ownership was taken).
The match self
, therefore, already refers to a borrowed instance of TestEnum
and the match-arm StructMem {value, is_valid}
binds via references (&i32
, and &bool
). This is why is_valid
ends up being a &bool
, not a bool
.
Upvotes: 3