当前位置:网站首页>Pointers in rust: box, RC, cell, refcell

Pointers in rust: box, RC, cell, refcell

2022-04-23 18:03:00 Xu Yeping

Rust The pointer in :Box、Rc、Cell、RefCell

author : Xu Yeping 2022-02-21

Rust It has its own &、* The operator , Variable reference and dereference can be realized . Why come up with these types of pointers ? The reason is to break through Rust Persistent ” Sharing is not writable 、 Writable but not shared “ Principles . Let's see. Rust Compiler ” Moral bottom line “ How to break through step by step .

1 Box type

I am here 《 Rust Of Box The pointer 》 This paper discusses in detail Box Characteristics . Take a simple example :

fn main() {
    
    let x = String::from("Hello!");
    let y = Box::new(x);
    println!("{:?}", y);
}

In fact, this code is almost equivalent to the following code :

fn main() {
    
    let x = String::from("Hello!");
    let y = &x;
    println!("{:?}", y);
}

There's another paragraph Box Code , Shows the usage when designing the linked list structure :

#[derive (Debug)]
struct Node {
    
    data: i32,
    next: Option<Box<Node>>,
}
fn main() {
    
    let x = Node {
    
        data: 123,
        next: None,
    };
    let y = Box::new(x);
    println!("{:?}", y);
}
---------------------------------
>cargo run
Node {
     data: 123, next: None }

I try to put Box Change to &, As a result, because of the problem of life cycle , I haven't been able to compile for a long time . Paste the code below , Which great God can give me some ?

#[derive (Debug)]
struct Node <'a>{
    
    data: i32,
    next: Option<&'a Node>,
}
fn main() {
    
    let x = Node {
    
        data: 123,
        next: None,
    };
    let y = Box::new(x);
    println!("{:?}", y);
}
---------------------------------
>cargo run
 --> src\main.rs:4:22
  |
4 |     next: Option<&'a Node>,
  |                      ^^^^ expected named lifetime parameter
  |
help: consider using the `'a` lifetime

Never mind & Can you replace it Box, Anyway, tell me about it ,Box Helped us simplify a lot of work , It's better than using it directly & It's easier .

2 Rc type

Look at the code below :

use std::rc::Rc;
fn main() {
    
    let x = Rc::new(123);
    let y = x.clone();
    println!("{:?}, {:?}", x, y);
}
---------------------------------------------------
cargo run
123, 123

In fact, logically speaking , It can also be used. & Instead of . The address of a variable can be assigned to multiple variables , Isn't it ? But rust Life cycle problems in , Enough for us to drink a pot . therefore ,Rc The existence value of is to avoid life cycle inspection , So that the same data can be referenced in multiple places .

3 Cell type

Cell Types are covered with read-only variables , Allow the program to modify the contents of variables . Even though Rust There is a principle ——“ Sharing is not writable , Writable but not shared ”, because Cell Seemingly read-only , therefore ,Cell Type of data can be referenced in multiple places , Realize that the same data can be modified by multiple shared references . because Cell Grammatically, it is read-only , So the compiler doesn't report errors .

Cell It can be used get Method returns data . Because of the execution of Copy Method , Therefore, it is required that the data must realize Copy characteristic .

use std::cell::Cell;
fn main() {
    
    let x = Cell::new(123);
    x.set(456);
    let y = x.get();
    println!("{:?}, {:?}", x, y);
}
------------------------------------------------------
>cargo run
Cell {
     value: 456 }, 456

4 RefCell

RefCell And Cell Basically the same , The difference lies in RefCell When reading content , The return is the reference , It's essentially a pointer . This is because RefCell The data to be packaged is not implemented Copy characteristic . The code example is as follows :

use std::cell::{
    Ref, RefCell};
fn main() {
    
    let x = RefCell::new("good".to_string());
    let a = &x;
    let b = &x;
    *a.borrow_mut() = "nice".to_string();
    *b.borrow_mut() = "best".to_string();
    let y: Ref<String> = x.borrow();
    println!("x = {:?}", x);
    println!("y = {:?}", y);
}
---------------------------------------------------
>cargo run
x = RefCell {
     value: "best" }
y = "best"

5 summary

  • Box And so on , Simplifies the variable life cycle problem .
  • Rc allow clone() Method to produce multiple copies of the variable , But these copies don't really allocate memory , But shared the same data .
  • Cell Syntactically, it is a read-only reference , In fact, it can be modified .Cell In principle, you can only refer to the implementation Copy Characteristic variables .
  • RefCell And Cell similar , But you can refer to unimplemented Copy Characteristic variables .

版权声明
本文为[Xu Yeping]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230544498483.html