【Rust问答】Box 和 Cell 之间有什么本质区别?
- 2020 年 2 月 20 日
- 筆記
Box 和 Cell 之间的本质区别是什么?两者主要的应用场景为何?通过一些搜索和文档阅读,我了解到两者确实有很多不同点,但是我一直没有找到对于“本质区别”这个概念的合理解答。
一些参考:
- https://rust.cc/article?id=37d1cb4f-5cc9-4adc-b41a-dbe4914bf4b5
- https://www.reddit.com/r/rust/comments/4cvc3o/what_are_cell_and_refcell_used_for
- https://users.rust-lang.org/t/confused-between-box-rc-cell-arc/10946/1
——
yuanyunchang 2020-01-17 08:49
Cell和RefCell是实现内部可变性的容器,在保持容器不被drop的情况下可以修改其中的值,而Box就做不到。
作者 JmPotato 2020-01-17 11:02
感谢回答,我昨天研究了一天这个问题,写了一篇文章来记录一下,欢迎帮忙纠错。https://ipotato.me/article/57
jmjoy 2020-01-17 12:14
不错!
yuanyunchang 2020-01-17 13:50
很多底层的东西都要用unsafe+指针,如果指针玩得溜也可以自己用unsafe整哈。
AlephAlpha 2020-01-17 14:56
Box
是一个指针,指向堆上的某个位置。和普通的指针不同的是,它独占了对数据的所有权。
Cell
其实__不是__一个指针,虽然经常会拿它跟各种智能指针对比。Cell<T>
只是把数据 T
包装一下,告诉你它有“内部可变性”。数据还是那些数据。
这带来的一个后果就是它们的大小不同:不管 T
是什么,Box<T>
都是一个指针的大小,Cell<T>
的大小和则和 T
一致。比如说:playground
Box
的常见用法就是利用其大小固定这一点。比如说我们可以这样定义一个链表:
enum List<T> { Cons(T, Box<List<T>>), Nil, }
不管链表实际有多长,List<T>
的大小是不变的,因为 Box<List<T>>
只是一个指针。
但如果把 Box
换成 Cell
,这就没法编译了,因为此时数据的大小会随着链表的长度而改变,Rust 没法在编译时知道要分配多少空间。
作者 JmPotato 2020-01-17 15:04
这个细节很好,感谢!
Yogaflre 2020-01-20 15:49
解释的很详细!那请问下Box和&又有什么区别呢?
ywxt 2020-01-26 20:40
Box是个智能指针,有所有权和生命周期,&只是一个引用,没有所有权,生命周期取决于借用对象。可以简单理解,Box持有数据,拿到Box相当于拿到数据,而&仅提供了一种访问数据的方式。