Rust 智能指针实现方法

 更新时间:2024年01月23日 10:30:18   作者:繁星遥可及  
这篇文章主要介绍了Rust 智能指针的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

Rust 第24节 智能指针

智能指针的实现

智能指针通常使用struct实现,
并实现Deref和Drop这两个trait

Deref trait:允许智能指针struct 的实例像引用一样使用

Drop triat: 允许你自定义当智能指针实例走出作用域时的代码

标准库中常见的智能指针

Box<T>:在heap内存上分配值
Rc<T>: 启用多重所有权的引用技术类型
Ref<T>     RefMut<T>     通过RefCall<T> 访问:在运行时而不是编译时强制借用规则的类型

使用Box 来指向Heap上的数据

他是最简单的智能指针

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

rust 编译时需要知道一个类型所占的空间大小

但是递归类型的大小在编译时无法确认大小

使用Box可以解决,Box是指针,大小确认

Deref Trait

Deref 解引用,我们可以自定义解引用运算符*的行为

通过Deref,智能指针可以像常规引用一样来处理

解引用运算符

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

使用box

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

自定义一个元组指针

struct Mypointer<T>(T); //结构体元组,只有一个成员
//元组结构体相当于没有成员名字的结构体,通过索引访问
impl<T> Mypointer<T> {
    fn new(x : T) -> Mypointer<T> {
        Mypointer(x)
    }
}
//要让其成为指针,需要实现Deref方法
impl<T> Deref for Mypointer<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.0
    }
}
    let y = Mypointer::new(5);
    assert_eq!(5,*y);

Deref 隐式解引用方法

当传入类型与函数接收类型不匹配时,如果参数实现了Deref trait,则编译器会自动调用Deref方法,对参数类型进行匹配;

例子:

fn hello(name :  & str) {
    println!("hello,{}",name);
}
    hello("Rust");
    let m = Mypointer::new(String::from("Rust"));
        //原始类型为 &mypointer<String>
        // deref &string
        // deref &str
    hello(&m);

Drop Trait

实现后,可以自定义值离开作用域时发生的动作

要求实现drop方法

在变量离开作用域时,会自动调用drop方法

例子:

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

不能手动调用.drop()方法

但是可以调用drop(变量)函数 进行手动注销

Rc引用计数智能指针

有时,一个值会有多个所有者

为了支持多重所有权,引入 Rc

Rc只能用于单线程场景

方法:

Rc::clone(&a)函数:增加引用计数

Rc::strong_count(&a): 获得引用计数

例子:

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....

通过不可变的引用,使你可以在程序不同部分之间共享只读数据

与clone()相比,属于浅拷贝,执行速度快

RefCell 和内部可变性

内部可变性:

允许在只持有不可变引用的前提下对数据进行修改

RefCell 在运行时检查所有权规则

只能用于单线程的代码

BoxRcRefCell
同一数据所有者一个多个一个
可变性、借用检查可变、不可变借用(编译时检查)不可变借用(编译时检查)可变、不可变借用(运行时检查)

正常情况下无法借用一个不可变的可变借用

let a = 10;
let b = &mut a;//错误

Refcall 的 .borrow_mut()方法:修改不可变引用的值

到此这篇关于Rust 智能指针的文章就介绍到这了,更多相关Rust 智能指针内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Rust之模式与模式匹配的实现

    Rust之模式与模式匹配的实现

    Rust中的模式匹配功能强大且灵活,它极大地提高了代码的表达力和可读性,本文主要介绍了Rust之模式与模式匹配,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • 从零开始使用Rust编写nginx(TLS证书快过期了)

    从零开始使用Rust编写nginx(TLS证书快过期了)

    wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 负载均衡, 静态文件服务器,websocket代理,四层TCP/UDP转发,内网穿透等,本文给大家介绍从零开始使用Rust编写nginx(TLS证书快过期了),感兴趣的朋友一起看看吧
    2024-03-03
  • Rust 枚举和模式匹配的实现

    Rust 枚举和模式匹配的实现

    枚举是 Rust 中非常重要的复合类型,也是最强大的复合类型之一,广泛用于属性配置、错误处理、分支流程、类型聚合等场景中,本文就来介绍一下Rust 枚举和模式匹配,感兴趣的可以了解一下
    2023-12-12
  • Rust中的函数指针详解

    Rust中的函数指针详解

    Rust是一种现代的系统编程语言,它支持函数指针。函数指针是指向函数的指针,可以将函数作为参数传递给其他函数或存储在变量中。Rust中的函数指针可以用于实现回调函数、动态分发和多态等功能。本文将介绍Rust中的函数指针的基本用法和高级用法。
    2023-05-05
  • Go调用Rust方法及外部函数接口前置

    Go调用Rust方法及外部函数接口前置

    这篇文章主要为大家介绍了Go调用Rust方法及外部函数接口前置示例实现,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Rust语言开发环境搭建详细教程(图文教程)

    Rust语言开发环境搭建详细教程(图文教程)

    本文主要介绍了rust编程语言在windows上开发环境的搭建方法,文中通过图文的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-02-02
  • Rust使用libloader调用动态链接库

    Rust使用libloader调用动态链接库

    这篇文章主要为大家介绍了Rust使用libloader调用动态链接库示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 一文弄懂rust声明宏

    一文弄懂rust声明宏

    Rust支持两种宏,一种是声明宏,一种是过程宏,本文主要介绍了一文弄懂rust声明宏,通过声明宏可以减少一些样板代码,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Rust生成随机数的项目实践

    Rust生成随机数的项目实践

    Rust标准库中并没有随机数生成器,常见的解决方案是使用rand包,本文主要介绍了Rust生成随机数的项目实践,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Rust版本号的使用方法详解

    Rust版本号的使用方法详解

    在 Rust 项目中,版本号的使用遵循语义版本控制(Semantic Versioning)原则,确保版本号的变化能准确反映代码的变更情况,本文给大家详细解释了Rust版本号用法,需要的朋友可以参考下
    2024-01-01

最新评论