More than code

More Than Code
The efficiency of your iteration of reading, practicing and thinking decides your understanding of the world.
  1. 首页
  2. daily
  3. 正文

Daily Rust 有关所有权和生命周期的一些问题

2022年1月27日 516点热度 0人点赞 0条评论

Daily Rust 有关所有权和生命周期的一些问题

首先看一段代码

use std::rc::Rc;

#[derive(Debug)]
struct Node {
    id: usize,
    downstream: Option<Rc<Node>>,
}

impl Node {
    pub fn new(id: usize) -> Self {
        Self {
            id,
            downstream: None,
        }
    }

    pub fn update_downstream(&mut self, downstream: Rc<Node>) {
        self.downstream = Some(downstream);
    }

    pub fn get_downstream(&self) -> Option<Rc<Node>> {
        self.downstream.as_ref().map(|v| v.clone())
    }
}

fn main() {
    let mut node1 = Node::new(1);
    let mut node2 = Node::new(2);
    let mut node3 = Node::new(3);
    let node4 = Node::new(4);
    node3.update_downstream(Rc::new(node4));

    node1.update_downstream(Rc::new(node3));
    node2.update_downstream(node1.get_downstream().unwrap());
    println!("node1: {:?}, node2: {:?}", node1, node2);
}

这个是一个简单的DAG(有向无环图)的示例

在图中,我们知道会有多个节点同时指向一个节点,那我们怎么在rust中用什么表示这样的数据结构呢?

如果节点的出边定义为对另一个节点的引用,那么我们就必须保证引用的节点的生命周期不比当前节点短,也就是为了保证引用有效

但是这样做的缺点就是对于节点的生命周期,我们要自己保证,所以就很容易出现悬垂引用的情况

所以在Rust中我们用RAII的方式来处理这种多个所有者的情况

具体的,就是使用Rc,在Rc的new中,我们会把原本的node移动进去,然后用Rc来帮我们管理

可以看到,在get_downstream中,我们返回一个节点的时候会把这个节点进行clone

这其实就相当于是对Rc的增加引用技术操作

之后当引用计数为0的时候, 我们就会把原本在Rc::new中移动进去的值销毁掉

还有一个细节就是我们在设置node2的下游节点的时候,不是直接设置的node3,而是先通过node1获得了他的一个Rc,然后再添加到node2中。因为Rc的new会移动我们的node,所以之后就不能再用node3了

然后是有关生命周期的一些点

在函数返回引用的时候,当&self或者&mut self出现在参数中的时候,返回值的生命周期和它相关联

我们可以考虑一下这里的semantic,当涉及到self的东西的时候,我们很有可能是在返回这个self中的一些数据。比如HashMap的get,我们返回的value不与传入进来的参数的生命周期有关,而是与self本身有关,因为我们返回的value是存储在self中的

对于如果我们要返回函数执行过程中得到的数据,那么无论参数如何,我们一定要返回的是值,或者说是move semantic,因为如果不把函数中得到的值move出来,函数结束后他就会被销毁

生命周期的标注大多数情况下可以通过仔细思考函数的作用(含义)来得到正确结果

当我们写Rust中需要很特别的处理各种错误问题的时候,这时候应该想一想是不是设计方面,或者是自己的实现需要重构

标签: daily rust
最后更新:2022年1月27日

sheep

think again

点赞
< 上一篇
下一篇 >

文章评论

取消回复

COPYRIGHT © 2021 heavensheep.xyz. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS