首页 > 其他分享 >[rust学习] 二、 rust中的智能指针

[rust学习] 二、 rust中的智能指针

时间:2023-04-04 20:22:27浏览次数:33  
标签:max self 智能 fn Rc RefCell rust 指针

  rust中智能指针大致分类

  以下内容提炼自rust官方文档:  https://doc.rust-lang.org/book/ch15-01-box.html

 

一、 Box<T>

    1. 使用例子:  

1 fn main() {
2     let b = Box::new(5);
3     println!("b = {}", b);
4 }

    2. 特性:

      a. 由Box指向的数据的内存分配是在堆上;

      b. 在编译期执行的可变借用与不可变借用的检查;

      c. 所有权拥有者只有1个;

    3. 大部分的使用场景:

      a. 编译时某类型大小不确定,但希望在大小确定的上下文中使用该类型的值;

      b. 有大量数据需要进行所有权的转移,但不希望进行copy操作;

                  c.  想拥有一个实现特定trait而不是某个确定类型的值 ;

     

二. Rc

    1. 使用例子:

enum List {
    Cons(i32, Rc<List>),
    Nil,
}

use crate::List::{Cons, Nil};
use std::rc::Rc;

fn main() {
    let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
    let b = Cons(3, Rc::clone(&a));
    let c = Cons(4, Rc::clone(&a));
}

    2. 特性:

      a.  Rc指向的数据可以有多个拥有者(可变借用只能有一个),这也是这个Rc指针会存在的初衷;

                  b.  每进行一次clone,其指向数据的强引用的计数次数会+1,只有当强引用次数为0时该指向数据所占内存才会被释放;有强引用这个概念,对应的就有一个弱引用的概念存在。弱引用是用来在一些循环引用的数据结构中使用的,用来防止发生环形引用从而产生的内存泄漏;

                  c.  Rc不是线程安全的,不能在多线程中使用;

      d. 在编译期执行的可变借用与不可变借用的检查;

 

    3. 使用场景:

      a. 共享一份数据到多个需要所有权的地方使用;

三. RefCell

    1. 使用例子:

 

pub trait Messenger {
    fn send(&self, msg: &str);
}

pub struct LimitTracker<'a, T: Messenger> {
    messenger: &'a T,
    value: usize,
    max: usize,
}

impl<'a, T> LimitTracker<'a, T>
where
    T: Messenger,
{
    pub fn new(messenger: &'a T, max: usize) -> LimitTracker<'a, T> {
        LimitTracker {
            messenger,
            value: 0,
            max,
        }
    }

    pub fn set_value(&mut self, value: usize) {
        self.value = value;

        let percentage_of_max = self.value as f64 / self.max as f64;

        if percentage_of_max >= 1.0 {
            self.messenger.send("Error: You are over your quota!");
        } else if percentage_of_max >= 0.9 {
            self.messenger
                .send("Urgent warning: You've used up over 90% of your quota!");
        } else if percentage_of_max >= 0.75 {
            self.messenger
                .send("Warning: You've used up over 75% of your quota!");
        }
    }
}
 1 #[cfg(test)]
 2 mod tests {
 3     use super::*;
 4     use std::cell::RefCell;
 5 
 6     struct MockMessenger {
 7         sent_messages: RefCell<Vec<String>>,
 8     }
 9 
10     impl MockMessenger {
11         fn new() -> MockMessenger {
12             MockMessenger {
13                 sent_messages: RefCell::new(vec![]),
14             }
15         }
16     }
17 
18     impl Messenger for MockMessenger {
19         fn send(&self, message: &str) {
20             self.sent_messages.borrow_mut().push(String::from(message));
21         }
22     }
23 
24     #[test]
25     fn it_sends_an_over_75_percent_warning_message() {
26         // --snip--
27 
28         assert_eq!(mock_messenger.sent_messages.borrow().len(), 1);
29     }
30 }

 

    2. 特性:

      a. 内部可变性。类似上面的代码例子,虽然send函数的入参是不可变的&self,由于使用了RefCell,依旧可以对sent_messages属性进行修改;

                  b. 类似Box,只有一个拥有者;

                  c. 非线程安全,不可在多线程中使用;

                  d. 运行时的借用检查,而非编译时;

 

    3. 使用场景:

      a. 类似示例代码一般,外部不可变,而内部属性想进行改变;

      b. 部分代码逻辑复杂,rust编译器在编译期完全分析出是否有内存安全是很困难的,可能产生误判断导致代码无法编译通过。在人工确保正确性的情况下,是用RefCell可以避免掉编译期的借用检查。

 

    4. 注意事项:

      a. 用 RefCell<Rc<T>> 这种结构可能导致环形引用,从而产生内存泄漏 ( 具体原因请看官方文档章节:https://doc.rust-lang.org/book/ch15-06-reference-cycles.html , 简单点说明就是因为RefCell的内部可变性,可能导致Rc指向的数据发生变动,从而与自己本身产生直接活间接的一个环形引用,由于强引用计数永远不为0,所以内存也就永远不会释放了 );

 

标签:max,self,智能,fn,Rc,RefCell,rust,指针
From: https://www.cnblogs.com/zhaohuaxishi/p/17287802.html

相关文章

  • 如何基于AI算法实现智慧工厂视频大数据智能预警平台搭建?
    当前我国正处于数字经济高速发展的时代,企业正面临着数字化“转型升级”的需求。那么,工厂该如何实现智能化转型目标呢?EasyCVR视频融合平台与AI智能分析网关,融合了边缘AI智能识别技术,部署了多种AI算法,能实现人脸、人体、车辆、物体、行为等智能检测,在工厂的智慧转型场景中发挥着重要......
  • 浅谈推进安全管理智能化的必要性
    安全管理是经济发展和社会进步过程中不可或缺的重要一环,是企业发展的生命线,是社会生活的安全网,与我们每个人都息息相关。随着科学技术的加速发展,数字时代的到来,推进安全管理智能化已经成为时代发展的必然要求,成为经济社会高质量发展的必然选择。第一,推进安全管理智能化,积极适应新时......
  • 智能AI代码工具Cursor的使用
      //ImportnecessarynamespacesusingSystem.Net.Http;usingSystem.Text;usingSystem.Threading.Tasks;//DefineamethodtosendamessagetotheWeChatgrouppublicasyncTaskSendMessageToWeChatGroup(stringmessage){//DefinetheWeChatgro......
  • 汽车智能化升级,以太网技术解锁全新未来
    随着汽车智能化和互联网的快速发展,汽车逐渐从传统的机械设备转变为具有智能化和互联网特性的智能交通工具。以太网技术作为汽车网络连接的基础,正在逐渐成为汽车智能化发展的关键技术之一。本文将介绍以太网技术在汽车领域的应用及测试方法。一、以太网技术在汽车领域的应用以太......
  • 这款高效稳定的DTU产品,让你的工业物联网应用更加智能化
    工业物联网应用正在不断地拓展和深化,而工业设备和传感器的无线通信则是其中的重要环节。随着物联网技术的不断发展,越来越多的企业正在关注如何提高生产效率和降低生产成本。然而,当前许多传统行业的工作方式存在着许多弊端,比如传统的人工抄表就无法做到精准,及时,费时费力效果还差;环......
  • Rust关键字及作用
    Rust中的关键字被特定用于定义语法规则和限制名称空间中的标识符。以下是Rust中所有的关键字及其作用:as:类型转换;async:声明异步函数;await:等待异步操作结果;break:结束循环或跳出循环语句块;const:声明常量;continue:继续下一轮循环;crate:当前crate的名称;dyn:动态分发trait......
  • 企业数字化转型的微仓智能存取系统
    尽管很多企业意识到数字化转型的必要,但是摆在我们眼前的仍是残酷现实,多少家企业口口声声说要转型,实则多在“纸上谈兵”:或迷茫无助,不知从何下手;或敷衍塞责,只做表面文章;亦或是认知偏差,在错误的道路上一骑绝尘;再或者,面对转型需要的早期资金投入,许多企业望而生畏。企业的数字化转型首先......
  • 无人智能售货柜赚钱吗
    无人智能售货柜是一种越来越受欢迎的商业模式,它通过智能化的技术手段,实现了自动售卖商品的功能,无需人工操作。那么,无人智能售货柜是否能够赚钱呢?答案是肯定的。无人智能售货柜的商业模式具有以下优势:一、降低人工成本由于无需人工操作,无人智能售货柜可以大幅降低人工成本,提高经营利......
  • 智能物料柜方案——基于物联网的智能仓储管理系统
    智能物料柜方案是一种基于物联网技术的智能仓储管理系统,它可以实现对物料的自动化管理、监控和控制。智能物料柜方案包括硬件设备、软件平台和网络连接,可以满足各种规模和需求的企业和组织。硬件设备包括智能柜、传感器、控制器等,它们可以实现对物料的存储、取出、归还等操作,并且可......
  • 智能制造具有哪些特点
    智能制造是一种以人工智能技术为基础,以实现制造业数字化、网络化、智能化为目标的制造模式。相较于传统制造模式,智能制造具有以下几个显著特点:一、技术驱动智能制造是以人工智能、机器学习、大数据分析等新兴技术为支撑的制造模式。通过技术的发展与应用,实现制造过程的高效性、精细......