SoFunction
Updated on 2025-04-11

Rust Intelligent Pointer Implementation Method

Rust Chapter 24 Smart Pointer

Implementation of smart pointers

Smart pointers are usually implemented using struct.
And implement the two traits of Deref and Drop

Deref trait: Allows instances of smart pointer struct to be used like references

Drop triat: Allows you to customize the code when the smart pointer instance goes out of scope

Common smart pointers in the standard library

Box<T>:existheapAllocate values ​​on memory
Rc<T>: Reference technology types that enable multiple ownership
Ref<T>     RefMut<T>     passRefCall<T> access:exist运行时而不是编译时强制借用规则的类型

Use Box to point to data on Heap

He is the simplest smart pointer

    let b = Box::new(5);
    println!("b = {}",b);

rust needs to know the size of space occupied by a type when compiling

However, the size of the recursive type cannot be confirmed at compile time

Using Box can solve it. Box is a pointer and size confirmation

Deref Trait

Deref dereference, we can customize the behavior of dereference operator*

With Deref, smart pointers can be processed like regular references

Dereference operator

    let x = 5;
    let y = &x;
    assert_eq!(5,x);
    assert_eq!(5,*y);

Using box

    let y = Box::new(5);
    assert_eq!(5,*y);

Customize a tuple pointer

struct Mypointer<T>(T); //Structure tuple, only one member// Tuple structure is equivalent to a structure without member names, accessed through indeximpl<T> Mypointer<T> {
    fn new(x : T) -> Mypointer<T> {
        Mypointer(x)
    }
}
//To make it a pointer, the Deref method needs to be implementedimpl<T> Deref for Mypointer<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.0
    }
}
    let y = Mypointer::new(5);
    assert_eq!(5,*y);

Deref implicit dereference method

When the incoming type does not match the function receiving type, if the parameter implements the Deref trait, the compiler will automatically call the Deref method to match the parameter type;

example:

fn hello(name :  & str) {
    println!("hello,{}",name);
}
    hello("Rust");
    let m = Mypointer::new(String::from("Rust"));
        //The original type is &mypointer<String>        // deref &amp;string
        // deref &amp;str
    hello(&amp;m);

Drop Trait

After implementation, you can customize the actions that occur when the value leaves the scope.

Required to implement drop method

When the variable leaves the scope, the drop method is automatically called

example:

impl<T> Drop for Mypointer<T> {
    fn drop(&mut self) {
        println!("run drop function----")
    }
}

Cannot call the .drop() method manually

However, you can call the drop (variable) function to manually log out

Rc reference count smart pointer

Sometimes, a value has multiple owners

To support multiple ownership, Rc is introduced

Rc can only be used in single-threaded scenarios

method:

Rc::clone(&a) function: Increase the reference count

Rc::strong_count(&a): Get the reference count

example:

enum Node2 {
    Next2(i32 ,Rc<Node2> ),
    Nul
}
use self::Node2::Next2;
use self::Node2::Nul;
.... main.....
    let a = Rc::new( Next2(5, Rc::new( Nul ) ));
    println!("a value is {}",Rc::strong_count(&a));
    let b = Rc::new( Next2(
        12, Rc::clone(&a)
        )
    );
    println!("after b :a value is {}",Rc::strong_count(&a));
    let c = Rc::new(
        Next2(  11, Rc::clone(&a)  )
    );
    println!("after c: a value is {}",Rc::strong_count(&a));
    {
        let d = Rc::new(
            Next2(  15, Rc::clone(&a)  )
        );
        println!("after d :a value is {}",Rc::strong_count(&a));
    }
    println!("end : a value is {}",Rc::strong_count(&a));
....end....

With immutable references, you can share read-only data between different parts of the program

Compared with clone(), it is a shallow copy and has a fast execution speed.

RefCell and internal variability

Internal variability:

Allows modification of data while holding only immutable references

RefCell Checks Ownership Rules at Runtime

Only used for single threaded code

Box Rc RefCell
Same data owner one Multiple one
Variability, borrowing check Variable, immutable borrowing (compilation-time check) Immutable borrowing (compile-time check) Variable, immutable borrowing (runtime check)

Under normal circumstances, an immutable variable borrow cannot be borrowed.

let a = 10;
let b = &amp;mut a;//mistake

Refcall's .borrow_mut() method: Modify the value of an immutable reference

This is all about this article about Rust smart pointer. For more related Rust smart pointer content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!