12|智能指针:从所有权看智能指针
智能指针
指针和指针的类型
- 深入了解
- 翻译
- 解释
- 总结
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 - TaoziArc本质上是个引用,所以不允许同时存在可变引用或者移动。
作者回复: 👍
2023-11-15归属地:上海2 - 刘丹在中大项目中,使用 Rust 甚至会有超越 Python 的开发效率。
作者回复: 对的,py代码量上来后,可维护性和可重构性比rust差得太远。
2023-11-15归属地:广东22 - $侯Box<T> 中的所有权分析 那里 说“Point 类型本身就是 move 语义的” 这里的Point中的元素不都是copy语义的吗,所以这个Point不是应该是copy语义的吗,为什么说是move语义的
作者回复: 这正是一个隐含的知识点,固定尺寸的结构体却默认不是可copy的。目的是为了防止不小心的产生额外复制负担。
2023-12-25归属地:浙江1 - Michaelplay_boxown() 和 play_own() 只能同时打开一个,这两个方法调用都会消耗所有权,导致没法调用另外一个。
作者回复: 👍
2023-11-15归属地:中国香港1 - duwoodlyarced.play_mutref(); // Arc<T>没有实现智能指针的DerefMut trait arced.play_own(); // 不能从Arc<T> 中移出值,除非T实现了Copy
作者回复: 对的,自己动手试验,得到最准确最全面的信息。👍
2023-11-15归属地:重庆1 - superggnarced.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归属地:北京