Rust 在函数参数中使用'ref'是否与自动获取引用相同?

Rust 在函数参数中使用'ref'是否与自动获取引用相同?,rust,Rust,Rust教程通常提倡通过引用传递参数: fn my_func(x: &Something) 这就需要在调用站点显式引用值: my_func(&my_value). 可以使用模式匹配中常用的ref关键字: fn my_func(ref x: Something) 我可以这样称呼它 my_func(my_value) 内存方面,这是像我期望的那样工作,还是在调用my_func然后获取副本的引用之前将my_值复制到堆栈上?复制值,然后引用副本 fn f(ref mut x: i

Rust教程通常提倡通过引用传递参数:

fn my_func(x: &Something)
这就需要在调用站点显式引用值:

my_func(&my_value).
可以使用模式匹配中常用的
ref
关键字:

fn my_func(ref x: Something)
我可以这样称呼它

my_func(my_value)

内存方面,这是像我期望的那样工作,还是在调用
my_func
然后获取副本的引用之前将
my_值复制到堆栈上?

复制值,然后引用副本

fn f(ref mut x: i32) {
    *x = 12;
}

fn main() {
    let mut x = 42;
    f(x);
    println!("{}", x);
}

输出:42

如果调用像
f(x)
这样的函数,那么
x
总是按值传递

fn f(ref x: i32) {
    // ...
}
相当于

fn f(tmp: i32) {
    let ref x = tmp;
    // or,
    let x = &tmp;

    // ...
}

i、 e.引用完全限于函数调用。

两个函数都将
x
声明为
&Something
。区别在于前者将引用作为参数,而后者希望它是常规堆栈值。举例说明:

#[derive(Debug)]
struct Something;

fn by_reference(x: &Something) {
    println!("{:?}", x); // prints "&Something""
}

fn on_the_stack(ref x: Something) {
    println!("{:?}", x); // prints "&Something""
}

fn main() {
    let value_on_the_stack: Something = Something;
    let owned: Box<Something> = Box::new(Something);
    let borrowed: &Something = &value_on_the_stack;

    // Compiles:
    on_the_stack(value_on_the_stack);

    // Fail to compile:
    // on_the_stack(owned);
    // on_the_stack(borrowed);

    // Dereferencing will do:
    on_the_stack(*owned);
    on_the_stack(*borrowed);

    // Compiles:
    by_reference(owned); // Does not compile in Rust 1.0 - editor
    by_reference(borrowed);

    // Fails to compile:
    // by_reference(value_on_the_stack);

    // Taking a reference will do:
    by_reference(&value_on_the_stack);
}
#[派生(调试)]
构造某物;
fn通过引用(x:&Something){
println!(“{:?}”,x);//打印“&某物”
}
堆栈上的fn(参考x:某物){
println!(“{:?}”,x);//打印“&某物”
}
fn main(){
让值在\u堆栈上:Something=Something;
拥有:盒子=盒子::新的(某物);
让我们借用:&Something=&value\u在\u堆栈上;
//汇编:
在\u堆栈上(值在\u堆栈上);
//未能编译:
//在\u堆栈上(拥有);
//在\u堆栈上(借用);
//取消引用可以:
在\u堆栈上(*拥有);
在\u堆栈上(*借用);
//汇编:
by_reference(owned);//不在Rust 1.0-editor中编译
参照(借用);
//未能编译:
//按_引用(_堆栈上的值_);
//做一个推荐人可以:
按引用(堆栈上的值);
}

由于_堆栈
上的
接受一个值,因此它被复制,然后副本与形式参数中的模式匹配(在您的示例中为
ref x
)。匹配将
x
绑定到复制值的引用。

如果值未实现
Copy
,则两个函数之间的差异将变得更加明显。例如,
Vec
不实现
Copy
,因为这是一个昂贵的操作,相反,它实现了
Clone
(需要特定的方法调用)

假设定义了两种方法

fn take_ref(ref v: Vec<String>) {}// Takes a reference, ish
fn take_addr(v: &Vec<String>) {}// Takes an explicit reference
但是,当引用是显式的时,如在
take_addr
中,不会移动
Vec
,而是通过引用传递。因此,本规范确实按照预期工作:

let v: Vec<String>; // assume a real value
take_addr(&v);
println!("{:?}", v);// Prints contents as you would expect
让v:Vec;//假设一个真实值
取地址(&v);
普林顿!(“{:?}”,v);//按预期打印内容
“由于\u堆栈上有一个值,因此它会被复制”
let v: Vec<String>; // assume a real value
take_addr(&v);
println!("{:?}", v);// Prints contents as you would expect