这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战
详解rust中的智能指针
智能指针是指有指针语义的符合类型,在rust里trait决定了类型的行为,rust里通过实现Dereftrait和Droptrait两者的其一就可以实现一个智能指针类型,这里Dereftrait实现了解引用的语义,而Drop则实现了析构的语义。
pub trait Deref{
type Target: ?Sized;
fn deref(&self) -> &Self::Target;
}
上面这段是标准库中的Deref trait,这里定义了deref方法,实现了解引用,这样就可以代表指针的行为。
impl<T: ?Sized> Deref for Box<T>{
type Target = T;
fn deref(&self) -> &T{
&**self
}
}
这段代码是标准库中对于Box智能指针实现的Deref trait源码,这里的deref方法使用了&**self实现了解引用,这里两个*分别是对self的解引用以及对于Box的内部数据的解引用。也就当我们使用*来解引用指针的时候,相当于我们调用了内部的deref方法,即*&T。
实现一个自己的智能指针
在这里定义了我们的智能指针结构体,先实现一个
new方法用来实例化结构体,接着实现了Dereftrait以及deref方法实现了解引用。
自动解引用
比如通过我们实现的智能指针,我们可以通过点操作,来调用实例化结构体的方法,比如
struct A{
param: &'statis str
}
impl A {
fn log(&self){
println!("{:?}",self.param)
}
}
当我们实现一个简单的结构体如上所示时,如果实例化一个结构体A1,接着通过智能指针包裹,则接下来可以通过智能指针的点操作来调用内部方法,非常有助于开发体验。
在rust中有String的字符串以及str类型的字符串切片,在我们日常开发中,如果函数参数为&str,而传入的参数为String类型时,会自动解引用。rust在String的内部实现了deref函数,让我们可以通过&(String::from("123"))的方法将它转换为&str,同时保证了内存安全。
注意:
- 使用
*x的方式解引用,等价于*(x.deref()) - 使用点调用或者函数参数的自动解引用 等价于
x.deref()
标准库中的智能指针
- Box
- Vec,String
- Rc, Arc //共享所有权容器(引用计数指针)
- HashMap<K,V>
在这里比较特殊的是HashMap,HashMap并没有在标准库中实现
Dereftrait,但实现了析构Droptrait。