您现在的位置是:热点 >>正文
揭开智能指针 Box 的神秘面纱
热点678人已围观
简介...
熟悉 c++ 的肯定知道 shared_ptr, unique_ptr, 而 Rust 也有智能指针 Box, Rc, Arc, RefCell 等等,本文分享 Box 底层实现
Box会在堆上分配空间,存储 T 值,并返回对应的指针。同时 Box 也实现了 trait Deref 解引用和 Drop 析构,当 Box 离开作用域时自动释放空间
入门例子
例子来自 the rust book, 为了演示方便,去掉打印语句
fn main() { let _ = Box::new(0x11223344); }
将变量 0x11223344 分配在堆上,所谓的装箱,java 同学肯定很熟悉。让我们挂载 docker, 使用 rust-gdb 查看汇编实现
Dump of&nbs揭开p;assembler code for function hello_cargo::main: 0x000055555555bdb0 <+0>: sub $0x18,%rsp 0x000055555555bdb4 <+4>: movl $0x11223344,0x14(%rsp) => 0x000055555555bdbc <+12>: mov $0x4,%esi智能 0x000055555555bdc1 <+17>: mov %rsi,%rdi 0x000055555555bdc4 <+20>: callq 0x55555555b5b0 <alloc::alloc::exchange_malloc> 0x000055555555bdc9 <+25>: mov %rax,%rcx 0x000055指针555555bdcc <+28>: mov %rcx,%rax 0x000055555555bdcf <+31>: movl $0x11223344,(%rcx) 0x000055555555bdd5 <+37>: mov %rax,0x8(%rsp) 0x000055555555bdda <+42>: lea 0 Bx8(%rsp),%rdi 0x000055555555bddf <+47>: callq 0x55555555bd20 <core::ptr::drop_in_place<alloc::boxed::Box>> 0x000055555555bde4 <+52>: add $0x18,%rsp 0x000055555555bde8 <+56>: retq End of assembloxer dump.
关键点就两条,alloc::alloc::exchange_malloc 在堆上分配内存空间,然后将 0x11223344 存储到这个 malloc 的地址上
函数结束时,将地址传递给 core::ptr::drop_in_place 去释放,因为编译器知道类型是 alloc::boxed::Box, 会掉用 Box 相应的 drop 函数
单纯的看这个例子,Box 并不神秘,对应汇编实现,和普通指针没区别,一切约束都是编译期行为
所有权 fn main() { let x = Box::new(String::from("Rust")); let y& 的nbsp;= *x; println!("x is {}", x); }
这个例子中将字符串装箱,其实没必要这么写,因为 String 广义来讲本身就是一种智能指针。这个例子会报错
3 | let y = *x; | -- value moved here 4 | &nbs神秘p; println!("x is {}", x); | ^ value borrowed here after move
*x 解引用后对应 String, 赋值给 y 时执行 move 语义,所有权不在了,所以后续 println 不能打印 x
let y = &*x;
可面纱以取字符串的不可变引用来 fix
底层实现 pub struct Box< T: ?Sized, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, >(Unique, A);
上面是 Box 的定义,可以看到是一个元组结构体,有两个泛型参数:T 代表任意类型,A 代表内存分配器。标准库里 A 是 Gloal 默认值。其中 T 有一个泛型约束 ?Sized, 表示在编译时可能知道类型大小,也可能揭开不知道,当然一般都用于不知道大小的场景,很少像上文一样存储 int
#[stable(feature = "rust1", since = "1.0.0")] unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Box<T, A> { fn drop(&mut self) { //智能 FIXME: Do nothing, drop is currently performed by compiler. } }
这是 Drop 实现,源码里也说了,由编译器实现
#[stable(feature = "rust1", since = "1.0.0")] impl Deref for Box<T, A> { type Target = T;&nbs指针p; fn deref(&self) -> &T { &**self } } #[stable(feature = "rust1", since = "1.0.0")] impl DerefMut for Box<T, A> { &nb Bsp;fn deref_mut(&mut self) -> &mut T { &mut **self } }
实现了 Deref 可以定义解引用行为,DerefMut 可变解引用。所以 *x 对应着操作 *(x.deref())
适用场景
官网提到以下三个场景,本质上 Box 和普通指针区别不大,所以用处不如 Rc, Arc, RefCell 广
当类型在编译期不知道大小,但代码场景还要求确认类型大小的时候 当你有大量数据,需要移动所有权,而不想 copy 数据的时候 trait 对象,或者ox称为 dyn 动态分发常用在一个集合中存储不同的类型上,或者参数指定不同的类型
官网有一个链表的实现
enum List { Cons(i32, List), Nil, }
上面代码是无法运行的,道理也很简单,这是一种递归定义。对应 c 代码也是不行的,我们一般要给 next 类型定义成指针才行
enum List { Cons(i32, Box), Nil, } use crate::List:: 的{Cons, Nil}; fn main() { let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil)))))); }
官网给的解决方案,就是将 next 变成了指针 Box , 算是常识吧,没什么好说的
Tags:
相关文章
标签: 福布斯 马斯克 特斯拉 SpaceX
热点云梦级3月11日云梦级消息,当地时间 3 月 10 日,《福布斯》发布第 40 届年度《全球亿万富豪榜》。过去一年,全球富豪财富增长速度前所未见,富人群体的财富规模继续快速扩大。今年共有 3428 人...
【热点】
阅读更多谷歌Gemini主动式助手更名“每日简报”,深度集成多源数据实现智能推送
热点谷歌旗下人工智能平台Gemini近日被曝出重大功能更新动向。根据最新的APK拆解及行业消息显示,谷歌计划将其研发中的主动式人工智能中心功能正式由“你的一天”(Your Day)更名为“每日简报”(Da...
【热点】
阅读更多微软Copilot免费开放GPT-5多文件推理能力:免费支持多文件同时分析
热点微软已悄然将强大的 多文件分析支持功能 引入其网页版和Windows11版 Copilot ,且无需付费订阅即可使用。此前,Copilot虽支持上传最多20个文件,但无法将它们关联起来。借助此次升级,...
【热点】
阅读更多
热门文章
最新文章
友情链接
- 标签: 康师傅
- https://www.dba.dk/soeg/?soeg=谷歌霸屏软件【tg:seogoogle987】4X4
- https://www.jusoen.com/addreng.asp?p1=谷歌霸屏软件【tg:seogoogle987】nEa
- https://www.ushmm.org/search/results.php?q=谷歌霸屏软件【tg:seogoogle987】,5xP
- https://www.sebson.de/en/search?query=谷歌霸屏软件【tg:seogoogle987】,H3W
- https://www.remit.co.jp/ne/?s=谷歌霸屏软件【tg:seogoogle987】,CVo
- https://www.duksung.ac.kr/search/front/Search.jsp?qt=谷歌霸屏软件【tg:seogoogle987】S3n
- https://www.welshmountainzoo.org/shop/index.php?routeproduct/search&tag=谷歌霸屏软件【tg:seogoogle987】,Bue
- https://www.nyif.com/catalogsearch/result/index/?f=sarbanesoxleyU&index=me_cms_pe&lit=20&mode=list&p=1&q=谷歌霸屏软件【tg:seogoogle987】,HhO
- https://www.kawainter.com/catalogsearch/result/?q=谷歌霸屏软件【tg:seogoogle987】,hoP
- https://www.navylookout.com/?ID=nSBR6Ivdu6lZg1yr2SDs30Lo5sTs76yJ&s=谷歌霸屏软件【tg:seogoogle987】,xZw
- https://www.simcoemuskokahealth.org/SearchResults.aspx?SearchQuery=谷歌霸屏软件【tg:seogoogle987】,H6q
- https://www.localfootdoc.com/?s=谷歌霸屏软件【tg:seogoogle987】,Au3
- https://www.randjleather.co.uk/index.php?route=product/search&tag=谷歌霸屏软件【tg:seogoogle987】,EWv
- https://www.springfieldlibrary.org/library/?s=谷歌霸屏软件【tg:seogoogle987】,P5A
- https://www.niaogebiji.com/pc/article/search?keyword=谷歌霸屏软件【tg:seogoogle987】,NxN
- https://www.lindseymedicalsupply.com/search/谷歌霸屏软件【tg:seogoogle987】,nm6
- https://www.ushmm.org/search/results/?ID=8s0587Oi8UTv74zPPM4fuhwjNpe2hsEE&q=谷歌霸屏软件【tg:seogoogle987】,DAy
- https://www.teamlab.art/pt/?submit=谷歌霸屏软件【tg:seogoogle987】,fBv
- https://nicolazzi.it/en/?s=谷歌霸屏软件【tg:seogoogle987】,oLW
- https://www.repetto.jp/item/search?action=QUERY&q=谷歌霸屏软件【tg:seogoogle987】,mJR
- https://www.lee.com/search?q=谷歌霸屏软件【tg:seogoogle987】,YDA
- https://www.realsporting.com/buscador?buscar=谷歌霸屏软件【tg:seogoogle987】,6Gb
- https://www.olx.ba/pretraga?trazilica=谷歌霸屏软件【tg:seogoogle987】,AFy
- https://www.tarleton.edu/?s=谷歌霸屏软件【tg:seogoogle987】,SaO
- https://www.nextavenue.org/?action=QUERY&s=谷歌霸屏软件【tg:seogoogle987】,5oZ
- https://www.u-bourgogne.fr/?cat=117&s=谷歌霸屏软件【tg:seogoogle987】,jp1
- https://www.smics.com/tc/site/search?token=谷歌霸屏软件【tg:seogoogle987】,0GC
- https://www.sonepar.ch/fr/search?q=谷歌霸屏软件【tg:seogoogle987】,pyY
- https://www.krisinformation.se/en/search?q=谷歌霸屏软件【tg:seogoogle987】,wMn
- https://www.remit.co.jp/pt/?action=CHECK&s=谷歌霸屏软件【tg:seogoogle987】,ZoR
- https://www.nbm.org/?action=QUERY&s=谷歌霸屏软件【tg:seogoogle987】,Pot
- https://www.schenckprocess.com/search?q=谷歌霸屏软件【tg:seogoogle987】,kPb
- https://www.luxurysociety.com/en/search?q=谷歌霸屏软件【tg:seogoogle987】,pkm
- https://www.temu.com/search_result.html?search_key=谷歌霸屏软件【tg:seogoogle987】wNy
- https://dict.naver.com/dict.search?dicQuery&query=谷歌霸屏软件【tg:seogoogle987】0hc
- https://www.searcychamber.com/list/search?AsfnA=DtkTQzs&q=谷歌霸屏软件【tg:seogoogle987】,aVt
- https://www.wheels24.gr/?action=CHECK&s=谷歌霸屏软件【tg:seogoogle987】,5SJ
- https://www.stonerealestate.com.au/?cat=100&s=谷歌霸屏软件【tg:seogoogle987】,18l
- https://www.teamlab.art/it/?submit=谷歌霸屏软件【tg:seogoogle987】,NIw
- https://store.line.me/search/sticker/ja?q=谷歌霸屏软件【tg:seogoogle987】fep
- https://www.ncetm.org.uk/search?action=CHECK&q=谷歌霸屏软件【tg:seogoogle987】,5T3
- https://www.reallywildbirdfood.co.uk/store/search?q=谷歌霸屏软件【tg:seogoogle987】,kXd
- https://www.rollingstone.it/?ID=DVMeu3AlmzZE1cuJ2FmgmO5TSCQRb3yh&s=谷歌霸屏软件【tg:seogoogle987】,Fkj
- https://www.teacherspayteachers.com/Browse/Price-Range/Free/Search:Western International University Physics degree=谷歌霸屏软件【tg:seogoogle987】,0jp
- https://www.ntv.co.jp/3min/search/?action=QUERY&q=谷歌霸屏软件【tg:seogoogle987】,hsp
- https://www.nissin.com/jp/search/?cat=105&q=谷歌霸屏软件【tg:seogoogle987】,Tzj
- https://www.monroecounty.gov/search/?q=谷歌霸屏软件【tg:seogoogle987】,CgI
- https://www.prattlibrary.org/search?q=谷歌霸屏软件【tg:seogoogle987】,KOT
- https://www.maafushidive.com?collections?vendors?q=谷歌霸屏软件【tg:seogoogle987】,qwp
- https://www.zalora.sg/catalog/?cat=112&q=谷歌霸屏软件【tg:seogoogle987】,q9T