Rust 在函数参数中使用'ref'是否与自动获取引用相同?
Rust教程通常提倡通过引用传递参数: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
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