Rust:通过引用自动传递

Yve*_*rès 5 rust

Rust教程经常提倡使用

fn my_func(x: &Something)
Run Code Online (Sandbox Code Playgroud)

通过引用传递参数.这使得在调用站点上显然需要明确地获取值参考:

my_func(&my_value).
Run Code Online (Sandbox Code Playgroud)

但我查了一下,可以使用模式匹配中常用的'ref'关键字来做:

fn my_func(ref x: Something)
Run Code Online (Sandbox Code Playgroud)

然后,我可以简单地称之为

my_func(my_value)
Run Code Online (Sandbox Code Playgroud)

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

A.B*_*.B. 14

复制该值,然后引用该副本.

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

fn main() {
    let mut x = 42;
    f(x);
    println!("{}", x);
}
Run Code Online (Sandbox Code Playgroud)

产量:42


nam*_*ess 6

这两个函数都声明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);
}
Run Code Online (Sandbox Code Playgroud)

由于on_the_stack获取了一个值,它被复制,然后复制与形式参数(ref x在您的示例中)中的模式匹配.匹配绑定x到复制值的引用.


huo*_*uon 5

如果您调用类似的函数,f(x)x始终按值传递。

fn f(ref x: i32) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

相当于

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

    // ...
}
Run Code Online (Sandbox Code Playgroud)

即,引用完全限于函数调用。