美文网首页
Rust Deref与自动解引用

Rust Deref与自动解引用

作者: 生若夏花_1ad0 | 来源:发表于2020-01-05 00:11 被阅读0次

    Deref和DerefMut都是Rust中的trait,用来对指针类型进行转化,得到指针所指向的内容。比如从Box<T>或Rc<T>中得到T,或是从String中得到&str。
    从名字中就可以看出来,这Deref是解引用得到一个借用,是共享引用,RerefMut是得到一个可变借用。

    定义如下,只要针对某种类型实现了这两个trait,就可以得到指针中的内容。

    trait Deref{
          type Target:?Sized;
          fn deref(&self) -> &Self::Target;
    }
    
    trait DerefMut:Deref{
          fn deref_mut(&mut self) -> &mut Self::Target;
    }
    

    另外我们经常使用的解引用操作符*其实就是调用了deref函数。例如

    let s:String = String::new();
    let s1:&str = s.deref();
    //let s2:str = *s;//实质上在编译器看来是*(s.deref()),注意因为str是一个不定长的类型,不能赋值,这里只是演示
    //let s3:str = *(s.deref());//跟s2一样
    let s4:&str = &*s;//跟s1一样
    let s5:&str = &&&&*s;//跟s4一样,自动解引用
    let s6:&str = &s as &str;//也会自动调用deref()
    

    我们可以看到,其实s和(s.deref())本质上一样,s.deref()和&*s一样

    至于自动解引用,就是为了方便程序员,在变量不满足条件的情况下,自动对变量使用解引用,比如rust的库中针对&str实现了很多字符串的操作,然而并没有针对string进行实现,但是我们可以直接使用string进行字符串操作,实际上是编译器自动把&string解引用为了&str。

    举个例子

    let s:String = String::new();
    let a = s.len();
    
    //其中len()的函数原型为
    impl str{
        fn len(&self) -> usize; 
    }
    

    传入的应该是str,但是实际上我们在程序中是对string进行了len的调用,在调用的时候,len接收到的参数是&string,因为编译器发现string没有len方法,因此尝试自动进行解引用,也就是调用deref(),把&string转换为了&str,因此程序可以正常运行。

    编译器发现不能够编译通过时,会在三种情况下尝试进行自动解引用,所有的三种情况如下:
    1.&T转为&U,其中T: Deref<Target=U>
    2.&mut T转为&mut U,其中T: DerefMut<Target=U>
    3.&mut T转为&U,其中T: Deref<Target=U>

    相关文章

      网友评论

          本文标题:Rust Deref与自动解引用

          本文链接:https://www.haomeiwen.com/subject/luxqactx.html