Rust: Ref Usage
2024-07-07
When using the match expression, the ref keyword allows the match arm to work with a reference instead of moving the variable.
The match
Expression
match y {
Some(ref p) => println!("Co-ordinates are {},{} ", p.x, p.y),
_ => panic!("no match!"),
}
Here, we use a
match
expression to handle the different possibilities of theOption
value stored iny
.Some(ref p)
: This arm matches wheny
contains aSome
value.ref p
creates a reference (&Point
) to thePoint
inside theSome
variant. This avoids consuming (moving) the value out of theOption
.- The code then prints the coordinates of the point using
p.x
andp.y
.
_
: This is a wildcard pattern that matches any other case (i.e.,None
).- If
y
isNone
, this arm executes and panics (abruptly ends the program) with the message “no match!“.
- If
When to Use ref
The primary purpose of ref
is to create a reference (&
) within a pattern. This is particularly useful in two main scenarios:
Pattern Matching with
match
,if let
, andwhile let
: When you want to match against a value and simultaneously create a reference to that value for further use within the match arm.let my_option: Option<i32> = Some(42); match my_option { Some(ref x) => println!("The value is: {}", x), // x is a reference to the i32 inside Some None => println!("No value found."), }
In this example,
ref x
creates a reference to thei32
value inside theSome
variant, allowing you to usex
directly without consuming (moving) the value out of theOption
.Destructuring with
let
: When you want to create references to parts of a structure or tuple.struct Person { name: String, age: u8, } let person = Person { name: "Alice".to_string(), age: 30 }; let Person { name: ref name_ref, age: ref age_ref } = person; println!("Name: {}, Age: {}", name_ref, age_ref); // name_ref and age_ref are references
Here,
ref name_ref
andref age_ref
create references to thename
andage
fields of theperson
struct.