Rust 智能指针(二)
1. Rc<T> 引用计数指针
Rc<T> 是引用计数指针,可以使用clone使得指针所指向的数据具有多个所有者。
enum List {
Cons(i32, Rc<List>),
Nil,
}
use 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));
}
需要注意的是,Rc<T>指针的数据是不可变的
2. RefCell<T> 内部可变指针
RefCell<T>指针可以绕过编译期借用检查,普通指针和引用同一时间只能有一个可变引用或者多个不可变引用。而RefCell<T>把这个检查推迟到了运行时。如果有引用违反了借用原则,程序会panic!
use std::cell::RefCell;
struct S{
data:i32
}
fn main() {
let s = RefCell::new(S{data:3});
s.borrow_mut().data=5;
println!("{}",s.borrow().data);
}
通过&self.borrow()获得一个不可变借用,&self.borrrow_mut()获得一个可变借用。
use std::cell::RefCell;
struct S{
data:i32
}
fn main() {
let s = RefCell::new(S{data:3});
let s1=s.borrow_mut();
let s2 = s.borrow_mut();
}
s有两个可变引用,这很明显违反了引用借用原则。所以运行后会得到一个panic。
thread 'main' panicked at 'already borrowed: BorrowMutError', src\libcore\result.rs:997:5
stack backtrace:
0: std::sys_common::backtrace::_print
at src\libstd\sys\windows\backtrace/mod.rs:95
at src\libstd\sys\windows\backtrace/mod.rs:82
at src\libstd\sys_common/backtrace.rs:71
1: std::panicking::default_hook::{{closure}}
at src\libstd\sys_common/backtrace.rs:59
at src\libstd/panicking.rs:197
2: std::panicking::default_hook
at src\libstd/panicking.rs:211
3: std::panicking::rust_panic_with_hook
at src\libstd/panicking.rs:474
4: std::panicking::continue_panic_fmt
at src\libstd/panicking.rs:381
5: rust_begin_unwind
at src\libstd/panicking.rs:308
6: core::panicking::panic_fmt
at src\libcore/panicking.rs:85
7: core::result::unwrap_failed
at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e\src\libcore/macros.rs:18
8: core::result::Result<T,E>::expect
at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e\src\libcore/result.rs:825
9: core::cell::RefCell<T>::borrow_mut
at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e\src\libcore/cell.rs:873
10: untitled::main
at src/main.rs:9
11: std::rt::lang_start::{{closure}}
at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e\src\libstd/rt.rs:64
12: std::panicking::try::do_call
at src\libstd/rt.rs:49
at src\libstd/panicking.rs:293
13: _rust_maybe_catch_panic
at src\libpanic_unwind/lib.rs:87
14: std::rt::lang_start_internal
at src\libstd/panicking.rs:272
at src\libstd/panic.rs:388
at src\libstd/rt.rs:48
15: std::rt::lang_start
at /rustc/3c235d5600393dfe6c36eeed34042efad8d4f26e\src\libstd/rt.rs:64
16: main
17: _tmainCRTStartup
18: mainCRTStartup
19: unit_addrs_search
20: unit_addrs_search
3.使用Rc<T>和RefCell<T>构建具有多个所有者的可变引用
use std::cell::RefCell;
use std::rc::Rc;
struct S{
data:i32
}
fn main() {
let s = Rc::new( RefCell::new(S{data:3}));
let s1 = Rc::clone(&s);
s1.borrow_mut().data=43;
println!("{}",RefCell::borrow(&s).data);
}
输出43
Rust 智能指针(二)的更多相关文章
- Rust 智能指针(一)
Rust 智能指针(一) 1.Box<T> Box<T>是指向堆中的指针. fn main() { let box = Box::new(3); println!(" ...
- 探讨 Rust 智能指针 | Vol.17
分享主题:<探讨 Rust 智能指针>| Vol. 17 分享讲师:苏林 分享时间: 周日晚上 2021-11-14 20:30-21:30 腾讯会议地址: https://meeting ...
- C++ 智能指针二
/* 智能指针shared_ptr注意点 */ #include <iostream> #include <string> #include <memory> // ...
- 智能指针(二):shared_ptr实现原理
前面讲到auto_ptr有个很大的缺陷就是所有权的转移,就是一个对象的内存块只能被一个智能指针对象所拥有.但我们有些时候希望共用那个内存块.于是C++ 11标准中有了shared_ptr这样的智能指针 ...
- 【校招面试 之 C/C++】第26题 C++ 智能指针(二)之 share_ptr
1.综述 shared_ptr 是一个标准的共享所有权的智能指针, 允许多个指针指向同一个对象. 定义在 memory 文件中(非memory.h), 命名空间为 std. shared_ptr 是为 ...
- 深入学习c++--智能指针(二) weak_ptr(打破shared_ptr循环引用)
1. 几种智能指针 1. auto_ptr: c++11中推荐不使用他(放弃) 2. shared_ptr: 拥有共享对象所有权语义的智能指针 3. unique_ptr: 拥有独有对象所有权语义的智 ...
- 智能指针--C++
智能指针(一):STL auto_ptr实现原理 智能指针实际上是一个类(class),里面封装了一个指针.它的用处是啥呢? 指针与内存 说到指针自然涉及到内存.我们如果是在堆栈(stack)中分配了 ...
- Rust入坑指南:智能指针
在了解了Rust中的所有权.所有权借用.生命周期这些概念后,相信各位坑友对Rust已经有了比较深刻的认识了,今天又是一个连环坑,我们一起来把智能指针刨出来,一探究竟. 智能指针是Rust中一种特殊的数 ...
- c++11新特性实战(二):智能指针
c++11添加了新的智能指针,unique_ptr.shared_ptr和weak_ptr,同时也将auto_ptr置为废弃(deprecated). 但是在实际的使用过程中,很多人都会有这样的问题: ...
随机推荐
- .NET总结--泛型与泛型集合,应用场景
泛型优点 1.提高代码复用性,代码简洁直观 2.直接存储数据类型免去数据类型之间得隐式转换 3.免去拆箱装箱过程,提高效率 4.数据类型安全,存储时会验证是否对应该类型 泛型集合 一. ArrayLi ...
- 关于windows10用c++部署libtorch过程中遇到的一些问题
libtorch1.0 vs2017 CMake3.14 windows10 无cuda 用c++调用pytorch模型官网上面有详细教程,也有很多博客,可以参考以下链接:https://blog.c ...
- Fluent Meshing分离边界层网格
源视频链接: https://pan.baidu.com/s/1SYB7UdRuXOGYXYwmxKADdw 提取码: h7qj
- docker时区问题
解决: dockerfile: RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime#update application timezoneR ...
- JavaScript初探系列(五)——this指向
一.涵义 this关键字是一个非常重要的语法点.毫不夸张地说,不理解它的含义,大部分开发任务都无法完成.this可以用在构造函数之中,表示实例对象.除此之外,this还可以用在别的场合.但不管是什么场 ...
- MyBatis(六):Mybatis Java API编程实现一对多、一对一
最近工作中用到了mybatis的Java API方式进行开发,顺便也整理下该功能的用法,接下来会针对基本部分进行学习: 1)Java API处理一对多.多对一的用法: 2)增.删.改.查的用法: 3) ...
- JDK性能监控命令
阅读原文 查看虚拟机进程:jps 命令 jps 命令可以列出所有的 Java 进程.如果 jps 不加任何参数,可以列出 Java 程序的进程 ID 以及 Main 函数短名称,如下所示. $ jps ...
- 如何在nginx下实现访问web网站密码认证保护的功能
在某些特定的环境下,我们希望nginx下的web站点在访问时需要用户输入账户密码才能访问.以便拒绝那些不速之客. 其实,配置起来也很简单,按照下面的步骤即可实现. 一.编辑虚拟主机配置文件. serv ...
- python中的绝对导入与相对导入,from __future__ import absolute_import的区别
相对导入:在不指明 package 名的情况下导入自己这个 package 的模块,比如一个 package 下有 a.py 和 b.py 两个文件,在 a.py 里 from . import b ...
- echarts柱状图坐标文字显示不完整解决方式
echarts柱状图坐标文字显示不完整解决方式 本文转载自:https://jingyan.baidu.com/article/ab69b2707a9aeb2ca7189f0c.html echart ...