Rust 语言从入门到实战
唐刚
Rust 语言中文社区联合创始人
5266 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 36 讲
Rust 语言从入门到实战
15
15
1.0x
00:00/00:00
登录|注册

12|智能指针:从所有权看智能指针

你好,我是 Mike。从今天开始,我们进入 Rust 进阶篇。
相对于基础篇,进阶篇更像外功招式,主要是掌握一些实用的基础设施,提高编程效率。这节课我们就在所有权视角下来学习 Rust 中的智能指针。

智能指针

学习智能指针之前,我们先来了解一下指针是什么。

指针和指针的类型

如果一个变量,里面存的是另一个变量在内存里的地址值,那么这个变量就被叫做指针。而我们前面讲到的引用(用 & 号表示)就是一种指针。
引用是必定有效的指针,它一定指向一个目前有效(比如没有被释放掉)的类型实例。而指针不一定是引用。也就是说,在 Rust 中,还有一些其他类型的指针存在,我们这节课就来学习其中一些。
我们这里要再次明晰一下引用的类型。引用分为不同的类型,单独的 & 符号本身没有什么意义,但是它和其他类型组合起来就能形成各种各样的引用类型。比如:
&str 是字符串切片引用类型。
&String 是所有权字符串的引用类型。
&u32 是 u32 的引用类型。
注:&str、&String、&u32 都是一个整体。
这三种都是引用类型,作为引用类型,它们之间是不同的。但是同一种引用类型的实例,比如 &10u32 和 &20u32,它们的类型是相同的。
那么,指针其实也类似,指向不同类型实例的指针,它的类型也是有区别的,这叫做指针的类型
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Rust中的智能指针在所有权概念下扮演着重要角色。本文深入探讨了智能指针的概念和应用,从指针和引用的基础知识出发,详细讨论了智能指针的灵活性和功能,以及其在实际应用中的作用。通过示例代码展示了智能指针的作用,特别是通过Box<T>智能指针实现了将资源强行创建在堆上,并精确控制资源的生命周期。文章还介绍了`Box<T>`的解引用、实现的trait以及作为函数参数的应用,以及对`&Box<T>`的引用操作。总的来说,本文通过深入浅出的方式,生动地介绍了智能指针的概念和应用,为读者提供了深入理解Rust中智能指针的基础知识。 文章还介绍了`Arc<T>`,作为共享所有权模型的智能指针,与`Box<T>`的区别和使用方法。`Arc<T>`的clone操作不要求T实现Clone trait,且不会克隆里面的内容,而是改变Arc的引用计数。另外,`Arc<T>`不提供修改T的能力,需要配合锁才能完成。与不可变引用&的区别在于,`Arc<T>`是共享了所有权模型,而&只是共享借用模型。整体而言,本文深入探讨了Rust中智能指针的概念和应用,以及`Arc<T>`的特点和使用方法,为读者提供了全面的技术视角和实用指导。 总的来说,本文通过深入浅出的方式,生动地介绍了智能指针的概念和应用,为读者提供了深入理解Rust中智能指针的基础知识。同时,文章还展示了`Arc<T>`作为共享所有权模型的智能指针,与`Box<T>`的区别和使用方法,为读者提供了全面的技术视角和实用指导。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Rust 语言从入门到实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(11)

  • 最新
  • 精选
  • asdf100
    在执行 Box::new() 创建 Box 实例时,具有 copy 语义的整数类型和具有 move 语义的 Point 类型行为不一样。整数会 copy 一份自己,Point 实例会把自己 move 到 Box 里面去。 ------ 是否可以理解为如果创建的对象有copy语义的话,则进行copy;否则进行move操作?

    作者回复: 对的

    2023-11-30归属地:澳大利亚
    3
  • Taozi
    Arc本质上是个引用,所以不允许同时存在可变引用或者移动。

    作者回复: 👍

    2023-11-15归属地:上海
    2
  • 刘丹
    在中大项目中,使用 Rust 甚至会有超越 Python 的开发效率。

    作者回复: 对的,py代码量上来后,可维护性和可重构性比rust差得太远。

    2023-11-15归属地:广东
    2
    2
  • $侯
    Box<T> 中的所有权分析 那里 说“Point 类型本身就是 move 语义的” 这里的Point中的元素不都是copy语义的吗,所以这个Point不是应该是copy语义的吗,为什么说是move语义的

    作者回复: 这正是一个隐含的知识点,固定尺寸的结构体却默认不是可copy的。目的是为了防止不小心的产生额外复制负担。

    2023-12-25归属地:浙江
    1
  • Michael
    play_boxown() 和 play_own() 只能同时打开一个,这两个方法调用都会消耗所有权,导致没法调用另外一个。

    作者回复: 👍

    2023-11-15归属地:中国香港
    1
  • duwoodly
    arced.play_mutref(); // Arc<T>没有实现智能指针的DerefMut trait arced.play_own(); // 不能从Arc<T> 中移出值,除非T实现了Copy

    作者回复: 对的,自己动手试验,得到最准确最全面的信息。👍

    2023-11-15归属地:重庆
    1
  • superggn
    arced.play_mutref() => 这个不能用是因为 Arc 这种提供多个引用的类型不支持可变引用 arced.play_own() => 这个不能用是因为 Arc 这种提供多个引用的类型不支持转移内部值的所有权 一开始我寻思这里会不会是直接抛出 mismatched type, 看 rustc 的提示发现不对, 后来想了想, 可能是因为 rust 找不到类型会先跑 deref coercion, deref coercion 匹配到了就不会报 mismatched type, 报错是在 deref coercion 过程中获取所有权的时候才出现? 总结下: Box<T>, Arc<T>, Rc<T> 调用 T 的方法, 机制都是 deref coercion Box 还好, 所有权拿走就拿吧, 但 Arc / Rc 这俩都可能会有不同的所有者, 里头的 T 不能是 mut 的, 所有权也不能放出去, 所以会错

    作者回复: 分析得非常棒!思路也很棒。

    2023-12-19归属地:北京
  • 鸠摩智
    值得注意的是,函数的入参是self:Box<Self>时,调用这个函数的只能是Box包起来的类型,比如这里的Point。 let p = Point{x:1,y:2}; p.play_boxown(); 会编译报错method `play_boxown` not found for this struct Point the method is available for `Box<Point>` here consider wrapping the receiver expression with the appropriate type Box::new(p).play_boxown(); 点操作符不会自动用Box包起来,但是会解开Box。

    作者回复: 对的,👍。自动解开是因为 Box<T> 实现了到 T 的 Deref:https://doc.rust-lang.org/std/boxed/struct.Box.html#impl-Deref-for-Box%3CT,+A%3E

    2023-11-16归属地:江苏
  • 下雨天
    let arced: Arc<Point> = Arc::new(Point{x: 10, y: 20}); 1. arced.play_mutref(); aced只提供不可变引用,play_mutref参数是可变引用。打开就会报错 2. arced.play_own(); // 不能用 play_own的参数self表示 Point , 而arced类型是Arc<Point> 不能强制转换。

    作者回复: 👍。是的,里面的T无法被移出Arc,这点与Box不同。

    2023-11-15归属地:湖北
  • -
    play_boxown() 和 play_own() 只能同时打开一个,两个都是所有权转移了,所以就只能调用一次。

    作者回复: 👍

    2023-11-15归属地:北京
收起评论
显示
设置
留言
11
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部