Rc与Box区别
来源:互联网 发布:手机淘宝彩票在哪里 编辑:程序博客网 时间:2024/06/10 20:40
咋一看觉得这两个概念差的很远,其实他们之间还是有联系的:
- 相同点:
他们都是在堆上分配资源,都只是保存了一个指向堆上的指针 - 区别:
- Box就是一个简单的指向堆的指针,并且指向堆的这个区域的指针只能有一个,owner lifetime结束就会释放堆上的资源
- Rc增加了一个计数(准确来说是两个指针),可以多个指针指向堆的这个区域,等所有的引用者lifetime结束了才释放堆上的资源
下面的代码为了看起来清爽点删除了注释
1 这个是Rc的定义
struct RcBox<T: ?Sized> { strong: Cell<usize>, weak: Cell<usize>, value: T,}pub struct Rc<T: ?Sized> { _ptr: NonZero<*mut RcBox<T>>,}
其中NonZero很简单,就是简单的包装了下T
pub struct NonZero<T: Zeroable>(T);
具体可以看:
http://doc.rust-lang.org/stable/src/alloc/rc.rs.html#172
2 Box定义如下:
pub struct Box<T>(Unique<T>);
http://doc.rust-lang.org/stable/src/alloc/boxed.rs.html#94
其中Unique定义如下:
pub struct Unique<T: ?Sized> { pointer: NonZero<*const T>, _marker: PhantomData<T>,}
http://doc.rust-lang.org/stable/src/core/ptr.rs.html#513-521
Unique里的marker是不占用存储空间的,可以暂时忽略掉
3 具体的例子:
use std::rc::Rc;#[derive(Debug)]struct Foo(i32);fn main(){ let r:Rc<Foo>; let b:Box<Foo>; { let r1 = Rc::new(Foo(100)); println!("r1:{:p}",&*r1); //clone计数 r = r1.clone(); //多处引用,都可以分别访问 println!("r1:{:?}",r1); let b1 = Box::new(Foo(200)); println!("b1:{:p},data:{}",&*b1,(*b1).0); //owner ship 转移了 b = b1; //b1不能再访问 //println!("{:?}",b1); } println!("{:?}",r); println!("r:{:p}",&*r); println!("{:?}",b); println!("b:{:p}",&*b);}
Play地址:http://is.gd/rGBLaW
输出结果:
r1:0x7f621582d010r1:Foo(100)b1:0x7f6215823020,data:200Foo(100)r:0x7f621582d010Foo(200)b:0x7f6215823020
Box,Rc 都是在堆上分配的,那么都可以存在于定义它的范围之外。
- Rc是通过引用计数的方式获得更长的lifetime,这儿r=r1.clone()就把堆上的对象的lifetime增加到了外层block对应的lifetime
- Box通过转移owner ship的方式把b1传递给了b从而让Box指向的堆上的资源没有被释放。
在这种情况下都可以通过不同的方式实现lifetime的扩张,但还是有区别的:
- Box方式转移了owner ship之后就不能再访问原来的b1了,也就是只能一个指针指向Box在堆上分配的资源
- Rc通过增加引用计数的方式实现了lifetime的扩张,并且r1还是继续使用的
0 0
- Rc与Box区别
- rc与webdriver区别
- content-box与border-box区别
- rc与deployment的区别
- Selenium RC 与 Web Driver 的区别
- LC滤波器与RC滤波器的区别
- display:box;与display:flex;区别
- MySQL 中隔离级别 RC 与 RR 的区别
- Hive:ORC与RC存储格式之间的区别
- MySQL 中隔离级别 RC 与 RR 的区别
- MySQL 中隔离级别 RC 与 RR 的区别
- rc.conf和rc.local的区别
- box-sizing中content-box和border-box的区别
- DC 与 RC
- RC微分与积分电路
- Linux系列:Linux下/etc/rc.local与/etc/init.d的区别与联系
- Linux下/etc/rc.local与/etc/init.d的区别与联系
- rc beta alpha版区别
- jsp的九大内置对象
- LeetCode Best Time to Buy and Sell Stock III
- 快速排序qsort()源码及使用实例。
- 欢迎使用CSDN-markdown编辑器
- boost ptree操作XML,方便又好用
- Rc与Box区别
- 数据结构-队列
- Android list 泛型 用Gson 转json字符串 出现 java.lang.StackOverflowError异常解决
- Andrew ng ML Coursera Quiz1
- 集成微信第三方登陆
- MyEclipse 强制杀掉后 INFO: Port busy 8009 java.net.BindException: Address already in use: JVM_Bind
- linux 查看文件内容的命令
- linux less从后向前查看日志信息
- tableView 和聊天对话一样,显示最新的数据,不用滑动