您现在的位置是:热点 >>正文
揭开智能指针 Box 的神秘面纱
热点134人已围观
简介...
熟悉 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&nbs智能p; 0x000055555555bdc1 <+17>: mov %rsi,%rdi 0x000055555555bdc4 <+20>: callq 0x55555555b5b0 <alloc::alloc::exchange_malloc> 0x000055555555bdc9 <+25>: mov %rax,%rcx 0x00005555指针5555bdcc <+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&nbs 的p;= *x; println!("x is {}", x); }
这个例子中将字符串装箱,其实没必要这么写,因为 String 广义来讲本身就是一种智能指针。这个例子会报错
3 | let y = *x; | -- value moved here 4 | &n神秘bsp; 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) { // F智能IXME: 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; &nb指针sp; fn deref(&self) -> &T { &**self } } #[stable(feature = "rust1", since = "1.0.0")] impl DerefMut for Box<T, A> { fn dere Bf_mut(&mut self) -> &mut T { &mut **self } }
实现了 Deref 可以定义解引用行为,DerefMut 可变解引用。所以 *x 对应着操作 *(x.deref())
适用场景
官网提到以下三个场景,本质上 Box 和普通指针区别不大,所以用处不如 Rc, Arc, RefCell 广
当类型在编译期不知道大小,但代码场景还要求确认类型大小的时候 当你有大量数据,需要移动所有权,而不想 copy 数据的时候 trait 对象,或者称为 dyn 动态分发常用在一个ox集合中存储不同的类型上,或者参数指定不同的类型
官网有一个链表的实现
enum List { Cons(i32, List), Nil, }
上面代码是无法运行的,道理也很简单,这是一种递归定义。对应 c 代码也是不行的,我们一般要给 next 类型定义成指针才行
enum List { Cons(i32, Box), Nil, } use crate::List::{Cons,& 的nbsp;Nil}; fn main() { let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil)))))); }
官网给的解决方案,就是将 next 变成了指针 Box , 算是常识吧,没什么好说的
Tags:
上一篇:木地板泡水了怎么处理
相关文章
标签: 卢伟冰 比亚迪 阿维塔06 广州地铁
热点Hello,大家早上好,又是元气满满的一天,先来浏览新鲜的早报吧~ 【卢伟冰谈 Air 手机】 小米集团合伙人、总裁、手机部总裁、小米品牌总经理卢伟冰 11 月 3 日谈到了 Air 手机:从实际的销...
【热点】
阅读更多OpenAI在印度推出ChatGPT Go新订阅计划,月费仅 5 美元
热点近日,OpenAI 宣布推出新的 ChatGPT Go 订阅计划,该计划目前仅在部分地区上线,例如印度。新的计划标志着 OpenAI 在其 AI 模型系列中再次迈出了重要一步,用户现在可以以大约每月5...
【热点】
阅读更多为什么信不过AI看病?数据集小、可靠性差,AI医疗任重道远
热点近年来,AI 在医疗诊断中的应用受到了越来越多的关注,也出现了一些实际的应用场景,如药物筛选、AI 诊断。但似乎正确的 AI 医疗诊断难以实现,这是哪些原因造成的呢?本文探讨并汇总了人们对 AI 医疗...
【热点】
阅读更多
热门文章
最新文章
友情链接
- 标签: 康师傅
- https://www.thedp.com/page/search?q=必应蜘蛛池租用【tg:seogoogle987】,2Zl
- https://www.klatreverden.no/search?q=必应蜘蛛池租用【tg:seogoogle987】,DtV
- https://www.shopping.com/search.html?keyword=必应蜘蛛池租用【tg:seogoogle987】,tvj
- https://www.varian.com/en-au/search?cat=113&search=必应蜘蛛池租用【tg:seogoogle987】,S8F
- https://www.tarleton.edu/?s=必应蜘蛛池租用【tg:seogoogle987】,EOj
- https://www.urmc.rochester.edu/news/search?q=必应蜘蛛池租用【tg:seogoogle987】,IXr
- https://www.symatoys.com/search.html?ID=UyMD6aO58bPrJvQAB1I0N69KzJBZeNPC&keyword=必应蜘蛛池租用【tg:seogoogle987】,BGn
- https://www.flickr.com/photos/tags/必应蜘蛛池租用【tg:seogoogle987】FYm
- https://www.paxnet.co.kr/search/jongmok?kwd=必应蜘蛛池租用【tg:seogoogle987】b9P
- https://www.toy-people.com/?s=必应蜘蛛池租用【tg:seogoogle987】,qHk
- https://www.wilsonart.com/catalogsearch/result/?action=CHECK&q=必应蜘蛛池租用【tg:seogoogle987】,phB
- https://www.tombow.com/en/search/必应蜘蛛池租用【tg:seogoogle987】,BBm
- https://www.mdbg.net/chinese/dictionary?page=worddict&wdrst=0&wdqb=必应蜘蛛池租用【tg:seogoogle987】,ukv
- https://www.schenckprocess.com/search?q=必应蜘蛛池租用【tg:seogoogle987】,20L
- https://www.kuaikanmanhua.com/sou/必应蜘蛛池租用【tg:seogoogle987】,MO1
- https://search.danawa.com/dsearch.php?query=必应蜘蛛池租用【tg:seogoogle987】bFv
- https://www.remit.co.jp/vi/?s=必应蜘蛛池租用【tg:seogoogle987】,gon
- https://www.duksung.ac.kr/search/front/Search.jsp?qt=必应蜘蛛池租用【tg:seogoogle987】36R
- https://xehay.vn/tim-kiem/=必应蜘蛛池租用【tg:seogoogle987】,3Up
- https://www.nyif.com/catalogsearch/result/index/?f=sarbanesoxleyU&index=me_cms_pe&lit=20&mode=list&p=1&q=必应蜘蛛池租用【tg:seogoogle987】,Xuj
- https://www.shacknews.com/editorial-search?q=必应蜘蛛池租用【tg:seogoogle987】,i6N
- https://www.uctronics.com/catalogsearch/result/?q=必应蜘蛛池租用【tg:seogoogle987】,0nr
- https://www.luxurysociety.com/en/search?q=必应蜘蛛池租用【tg:seogoogle987】,iYG
- https://www.nslcleaders.org/?s=必应蜘蛛池租用【tg:seogoogle987】,PwL
- https://www.mexperience.com/?T=1686132112324&s=必应蜘蛛池租用【tg:seogoogle987】,TpK
- https://www.normani.de/search?q=必应蜘蛛池租用【tg:seogoogle987】,9Dv
- https://www.jusoen.com/addreng.asp?p1=必应蜘蛛池租用【tg:seogoogle987】Tlr
- https://www.simcoemuskokahealth.org/SearchResults.aspx?SearchQuery=必应蜘蛛池租用【tg:seogoogle987】,BHz
- https://www.lindseymedicalsupply.com/search/必应蜘蛛池租用【tg:seogoogle987】,Hbd
- https://www.pinkpanda.ro/magazin/ingrijirea-tenului?page=87&q=必应蜘蛛池租用【tg:seogoogle987】,uIh
- https://www.safetv.go.kr/base/search/view?searchWord=必应蜘蛛池租用【tg:seogoogle987】8kN
- https://www.smics.com/tc/site/search?token=必应蜘蛛池租用【tg:seogoogle987】,kCM
- https://www.whatsonstage.com/search?cat=64&term=必应蜘蛛池租用【tg:seogoogle987】,Cmo
- https://www.metaltix.com/?view=tours&filter=search&q=必应蜘蛛池租用【tg:seogoogle987】,XLr
- https://www.reginatangoshoes.com/en/catalogsearch/result/index/?T=1686132113407&q=必应蜘蛛池租用【tg:seogoogle987】,JkQ
- https://www.rotherham.gov.uk/site-search/results/?q=必应蜘蛛池租用【tg:seogoogle987】,lWF
- https://www.laoairlines.com/?action=QUERY&s=必应蜘蛛池租用【tg:seogoogle987】,t0I
- https://www.youm7.com/Home/Search?allwords=必应蜘蛛池租用【tg:seogoogle987】,XdO
- https://www.vocabulary.com/dictionary/必应蜘蛛池租用【tg:seogoogle987】,yEu
- https://www.world-architects.com/en/search?term=必应蜘蛛池租用【tg:seogoogle987】,uR1
- https://www.whiterock2008.com.tw/search?q=必应蜘蛛池租用【tg:seogoogle987】,5Wu
- https://www.otakuninjahero.com/en/search/必应蜘蛛池租用【tg:seogoogle987】,4LM
- https://www.wellbees.com/catalogsearch/result/?action=CHECK&q=必应蜘蛛池租用【tg:seogoogle987】,dTv
- https://www.sensorshop24.de/catalogsearch/result/index/?type=132&q=必应蜘蛛池租用【tg:seogoogle987】,TV1
- https://www.ussalabama.com/?action=CHECK&s=必应蜘蛛池租用【tg:seogoogle987】,dhI
- https://wydden.com/?ID=r8w9WMSKWkOcmiaFWaUv0dzMdqZWfKtF&s=必应蜘蛛池租用【tg:seogoogle987】,cBR
- https://www.scq.ubc.ca/?page=2&s=必应蜘蛛池租用【tg:seogoogle987】,TO8
- https://www.revere.org/search?action=SEARCH&q=必应蜘蛛池租用【tg:seogoogle987】,gux
- https://xn--lgernevedlystskoven-lxb.dk/search/必应蜘蛛池租用【tg:seogoogle987】,Tue
- https://www.southmeadows.co.uk/2019/07/?s=必应蜘蛛池租用【tg:seogoogle987】,WNK