Location>code7788 >text

Usage and differences of *, &, mut, &mut, ref, ref mut in Rust

Popularity:625 ℃/2024-07-25 15:30:25

Usage and differences of *, &, mut, & mut, ref, ref mut in Rust

existRust Middle.*refmut& cap (a poem)ref mut are keywords and operators for dealing with referencing, dereferencing, and mutability that have different uses in different contexts.

One,* dereference

* belongs to the operator

1. Role

Used to dereference a pointer or reference to access the value it points to.
By dereferencing, you can get the actual value from a pointer or reference.

2. Usage

2.1. Dereferencing immutable references

fn main() {
let x = 5; let y = &x; // y is an immutable reference to x.
let y = &x; // y is an immutable reference to x. println!
println!("y: {}", *y); // get the value of x by dereferencing y, output: y: 5
}

2.2. Dereferencing variable references

fn main() {
let mut x = 10; let y = &mut x; // y is a mutable reference to x.
    let y = &mut x; // y is a mutable reference to x
    *y += 5; // change the value of x by dereferencing y
    println!("x: {}", x); // output: x: 15
}

2.3. Dereferencing pointers

fn main() {
let x = 42;
    let y = &x as *const i32; // create immutable bare pointer
    unsafe {
        println!("y: {}", *y); // Dereference the immutable bare pointer.
    }

let x = Box::new(10); // Box smart pointer.
    println!("x: {}", *x); // Dereference Box, get its value, output: x: 10
}

Two,& borrow sth. for one's own use

& is also an operator

1. Role

Creates an immutable reference to a value that allows reading without acquiring ownership; the value is read-only for the duration of the reference.

2. Usage

2.1 Immutable references

fn main() {
    let x = 10; // let y = &x; // y is an immutable reference to x.
    let y = &x; // y is an immutable reference to x.
    println!("y: {}", y); // Output: y: 10
}

2.2. Borrowing from functions

fn print_value(x: &i32) {
    println!("Value: {}", x);
}

fn main() {
    let a = 10; print_value(&a); //a)
    print_value(&a); // pass an immutable reference to a
}

2.3. use in match

fn main() {
	let reference = &4;
    match reference {
        &val => println!("Got a value via destructuring: {:?}", val),
    }
}

2.4. Use in structures

struct Point<'a> {
    
    
}
fn main() {
    let x = 10; let y = 20; } fn main() {
    
    let point = Point { x: &x, y: &y }; // Initialize struct fields by reference.
    println!("Point: ({}, {})", , ); // Output: Point: (10, 20)
}

2.5. Use in collections

fn main() {
    let vec = vec![1, 2, 3]; for val in &vec {
    for val in &vec {
        println!("Value: {}", val); // output: 1, 2, 3
    }
}

2.6 Use in slicing

fn main() {
    let s = String::from("hello");
    let slice = &s[0..2]; // Create a slice of the string.
    println!("Slice: {}", slice); // Output: Slice: he
}

Three,mut changeable

mut is a keyword

1. Role

Declaring a variable or reference as mutable allows you to modify its value.

2. Usage

2.1 Variable variables

fn main() {
    let mut x = 5; // x is mutable
    x += 1; println!
    println!("x: {}", x); // output: x: 6
}

2.2. Variable parameters in functions

fn increment(mut num: i32) -> i32 {
    num += 1;
    num
}

2.3 Variable references

fn main() {
    let mut x = 5.
    let y = &mut x.
    let mut x = 5; let y = &mut x; *y += 1; println!
    println!("{}", x); // output 6
}

2.4 Variable structures

struct Point {
    x: i32,
    y: i32,
}
fn main() {
    let mut p = Point { x: 0, y: 0 };
     = 5;
     = 10;
    println!("Point: ({}, {})", , ); // exports Point: (5, 10)
}

2.5 Variable tuples

let mut tuple = (5, 10);
tuple.0 = 15;

2.6. use in match

match Some(10) {
    Some(mut value) => {
        value += 1;
        println!("{}", value); // exports 11
    }
    None => {},
}

2.7. Use in collections

let mut vec = vec![1, 2, 3];
for num in &mut vec {
    *num += 1;
}
println!("{:?}", vec);

Four,&mut variable borrowing reference

&mut Neither an operator nor a keyword.

1. Role

Creates a mutable reference to a value, allowing the value to be modified without taking ownership.

2. Usage

2.1 Variable references

fn main() {
    let mut x = 10;
    let mut x = 10; {
        let y = &mut x; // y is a mutable reference to x
        *y += 5; // modify the value of x
    } // y's lifecycle ends when the mutable borrowing of x ends.
    println!("x: {}", x); // output: x: 15
}

2.2. Variable References in Functions

fn add_one(x: &mut i32) {
    *x += 1;
}

fn main() {
    let mut a = 10; } fn add_one(&mut a)
    add_one(&mut a); // pass a mutable reference to a
    println!("a: {}", a); // output: a: 11
}

2.3. Variable references in structures

struct Point<'a> {
    x: &'a mut i32, y: &'a mut i32, {
    
}
fn main() {
    let mut x = 10; let mut y = 20; } fn main()
    
    let point = Point { x: &mut x, y: &mut y }; // Initialize structure fields with mutable references
    * += 1; let mut y = 20; let point = Point { x: &mut x: y: &mut y }
    * += 1; println!
    println!("Point: ({}, {})", , ); // Output: Point: (11, 21)
}

2.4. Variable references in collections

fn main() {
    let mut vec = vec![1, 2, 3]; for val in &mut vec {
    for val in &mut vec {
        *val += 1; // modify the elements in the set
    }
    println!("{:?}" , vec); // output: [2, 3, 4]
}

2.5. use in match

fn main() {
    let mut pair = (10, 20);
    match pair {
        (ref mut x, ref mut y) => {
            *x += 1;
            *y += 1;
            println!("x: {}, y: {}", x, y); // exports: x: 11, y: 21
        },
    }
}

2.6. Use in structures

struct Counter {
    value: i32,
}
impl Counter {
    fn increment(&mut self) {
         += 1;
    }
}
fn main() {
    let mut counter = Counter { value: 0 };
    (); // Calling Methods with Variable References
    println!("Counter value: {}", ); // exports: Counter value: 1
}

Five,ref Creating references in pattern matching

ref Belongs to the keyword

1. Role

Borrow immutable references to values in pattern matching instead of taking ownership.

2. Usage

2.1. Use in tuples

fn main() {
    let tuple = (1, 2); // x and y are immutable references to elements in tuple.
    let (ref x, ref y) = tuple; // x and y are immutable references to elements in tuple.
    println!("x: {}, y: {}", x, y); // output: x: 1, y: 2
}

2.2. use in match

fn main() {
    let pair = (10, 20);
    match pair {
        (ref x, ref y) => {
            println!("x: {}, y: {}", x, y); // x and y are immutable references to the elements of pair.
        }
    }
}

2.3. use in if let / while let

// if let
fn main() {
    let some_value = Some(42);
    if let Some(ref x) = some_value {
        println!("Found a value: {}", x); // x be some_value Immutable references to the
    }
}
// while let
fn main() {
    let mut stack = vec![1, 2, 3];
    while let Some(ref x) = () {
        println!("Popped: {}", x); // x be stack 中最后一个元素Immutable references to the
    }
}

2.4. Use in functions

fn print_ref((ref x, ref y): &(i32, i32)) {
    println!("x: {}, y: {}", x, y); // x and y are immutable references to elements of the tuple
}
fn main() {
    let pair = (10, 20); print_ref(&pair)
    print_ref(&pair); // pass a reference to pair
}

2.5. Use in for loops

fn main() {
    let vec = vec![1, 2, 3];
    for ref x in &vec {
        println!("x: {}", x); // x is an immutable reference to an element in vec!
    }
}

Six,ref mut Creating Variable References in Pattern Matching

ref mut Belongs to keywords

1. Role

Borrows a variable reference to a value in pattern matching, allowing the value to be modified.

2. Usage

2.1. use in match

fn main() {
    let mut pair = (10, 20);
    match pair {
        (ref mut x, ref mut y) => {
            *x += 1;
            *y += 1;
            println!("x: {}, y: {}", x, y); // exports: x: 11, y: 21
        }
    }
    // pair has been modified.
}

2.2. use in if let / while let

fn main() {
    let mut some_value = Some(42);
    if let Some(ref mut x) = some_value {
        *x += 1;
        println!("Found a value: {}", x); // exports: Found a value: 43
    }
}
fn main() {
    let mut stack = vec![1, 2, 3];
    while let Some(ref mut x) = () {
        *x += 1;
        println!("Popped: {}", x); // exports: Popped: 4, Popped: 3, Popped: 2
    }
}

2.3. Use in functions

fn increment_tuple((ref mut x, ref mut y): &mut (i32, i32)) {
    *x += 1;
    *y += 1;
}

fn main() {
    let mut pair = (10, 20);
    increment_tuple(&mut pair); // pass on to sb else pair variable reference
    println!("pair: {:?}", pair); // exports: pair: (11, 21)
}

2.4. Deconstructing assignments

fn main() {
    let mut pair = (10, 20);
    let (ref mut x, ref mut y) = pair;
    *x += 1;
    *y += 1;
    println!("x: {}, y: {}", x, y); // exports: x: 11, y: 21
    println!("{:?}", pair); // (11, 21)
}

VII. Summary

  • *: The dereference operator, used to access the type of value pointed to by a pointer or reference.
  • &: Borrowing operator for creating immutable references of types that allow read-only access.
  • mut: Keyword for declaring the type of a variable or parameter that allows its value to be modified.
  • &mut: Borrowing operator for creating types of mutable references that allow read and write access.
  • ref: Keyword in pattern matching for creating types with immutable references to avoid ownership transfer.
  • ref mut: Keyword in pattern matching for creating types of variable references that allow modification of the value of the reference.