这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战
详解rust中的智能指针
智能指针是指有指针语义的符合类型,在rust
里trait决定了类型的行为,rust
里通过实现Deref
trait和Drop
trait两者的其一就可以实现一个智能指针类型,这里Deref
trait实现了解引用的语义,而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
方法用来实例化结构体,接着实现了Deref
trait以及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并没有在标准库中实现
Deref
trait,但实现了析构Drop
trait。