详解rust中的智能指针

1,072 阅读2分钟

这是我参与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

实现一个自己的智能指针

image.png 在这里定义了我们的智能指针结构体,先实现一个new方法用来实例化结构体,接着实现了Dereftrait以及deref方法实现了解引用。

自动解引用

比如通过我们实现的智能指针,我们可以通过点操作,来调用实例化结构体的方法,比如

struct A{
    param: &'statis str
}
impl A {
    fn log(&self){
        println!("{:?}",self.param)
    }
}

当我们实现一个简单的结构体如上所示时,如果实例化一个结构体A1,接着通过智能指针包裹,则接下来可以通过智能指针的点操作来调用内部方法,非常有助于开发体验。 在rust中有String的字符串以及str类型的字符串切片,在我们日常开发中,如果函数参数为&str,而传入的参数为String类型时,会自动解引用。rustString的内部实现了deref函数,让我们可以通过&(String::from("123"))的方法将它转换为&str,同时保证了内存安全。 注意:

  • 使用*x的方式解引用,等价于*(x.deref())
  • 使用点调用或者函数参数的自动解引用 等价于x.deref()

标准库中的智能指针

  1. Box
  2. Vec,String
  3. Rc, Arc //共享所有权容器(引用计数指针)
  4. HashMap<K,V> 在这里比较特殊的是HashMap,HashMap并没有在标准库中实现Dereftrait,但实现了析构Droptrait。