Rust引用和解引用

8fq7wneg  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(172)

下面是一个简短的Rust代码片段,我试图用它来理解Rust的引用和解引用:

fn main() {
    let mut i: i32 = 1;
    println!("i in main: {}", i);
    increment(&mut i);
    println!("i in main: {}", i);

    let mut a = String::from("ABCD");
    println!("a in main: {}", a);
    addchr(&mut a);
    println!("a in main: {}", a);
}

pub fn increment(i: &mut i32) {
    *i += 1;
    println!("i in increment: {}", *i);
}

pub fn addchr(s: &mut String) {
    s.push('a');
    println!("a in addchr: {}", s);
}

字符串
在整数的情况下,接收引用的函数需要解引用它(*i),但在字符串的情况下不需要(解引用似乎是“自动”的)。
是什么造成了这种差异?是否仅仅是关于内存分配的位置(堆栈还是堆)?

m3eecexj

m3eecexj1#

这是因为方法调用的语法。每个方法都有一个“receiver”参数(称为self及其变体)。这意味着my_string.push(...)基本上是 * String::push(&mut my_string, ...)的语法糖,因为push方法的接收者是&mut self
在你的例子中,s: &mut String和这个方法调用desugaring不需要任何额外的引用/解引用操作。
但是对于i32,add赋值操作符直接作用于mut i32(注意:没有引用),因此您需要使用*操作符解引用&mut i32。这只是因为您直接使用了+=操作符,如果您要使用在i32上定义的AddAssign::add_assign方法,则wouldn't need to dereference either

  • 实际上我不知道这个语法糖是否就是编译器如何做到这一点的,但我相信无论它做什么都是等效的,因为deref强制将删除任何不必要的引用。

相关问题