В параметрах функции, в чем разница между использованием ключевого слова ref и символа &? - PullRequest
0 голосов
/ 21 января 2019

В этом коде sref1 и sref2 являются адресами s, и адреса одинаковы.В чем разница между ref и &?

fn main() {
    let s = String::from("hello");
    let sref1 = &s;
    let ref sref2 = s;
    println!("{:p}", sref1);
    println!("{:p}", sref2);

    f1(&s);
    f2(s);
}

fn f1(_s: &String) {
    println!("{:p}", _s);
}

fn f2(ref _s: String) {
    println!("{:p}", _s);
}

_s в f1 и f2 также является адресом строки, f2 станет владельцем, ноадрес, напечатанный f2, не совпадает с адресом, напечатанным f1.Почему?

Ответы [ 3 ]

0 голосов
/ 21 января 2019

& применяется к rvalue (типу), в то время как ref применяется к lvalue (имени переменной), но они оба делают одно и то же.

ref было полезно внутри шаблонапотому что у вас есть доступ только к lvalue:

#![feature(core_intrinsics)]

fn print_type<T>(_: T) {
    println!("{}", unsafe { std::intrinsics::type_name::<T>() })
}

fn main() {
    let opt = Some(0);

    match opt {
        Some(ref i) => print_type(i), // &i32
        None => (),
    }
}

Однако сегодня это ключевое слово не очень полезно, потому что сопоставление с образцом является более "умным".Он понимает, что если вы заимствуете соответствующее значение, это означает, что вы хотите заимствовать внутреннее:

match &opt {
    Some(i) => print_type(i), // &i32
    None => (),
}
0 голосов
/ 21 января 2019

В параметрах функции, в чем разница между использованием ключевого слова ref и символом &?

Вы уже ответили на свой вопрос :

[с использованием ref] станет владельцем

Право собственности на переменную передается функции, а затем берется ссылка на перемещенную переменную.То есть

fn f2(ref _s: String) {}

эквивалентно

fn f2(s0: String) {
    let _s = &s0;
    // or 
    // let ref _s = s0;
}

Если вы используете &String (, который вы не должны ), функция не принимаетвладение переменной, только ссылка на нее.

адрес, напечатанный [...] не совпадает

Да, поскольку переменная была перемещена.Когда переменная перемещается, адрес, по которому она расположена, может измениться.Вот почему это называется «перемещение».

См. Также:

0 голосов
/ 21 января 2019

В шаблонах & разрушает заем, ref привязывается к местоположению по ссылке, а не по стоимости.

Другими словами, & позволяет вам достичь заимствования, а ref говорит: «возьмите заем в этом месте в соответствии с тем, что мне подходит»

& и ref являются противоположностями.

#![feature(core_intrinsics)]

fn main() {
    let x = &false;
    print_type_name_of(x);

    let &x = &false;
    print_type_name_of(x);

    let ref x = &false;
    print_type_name_of(x);
}

fn print_type_name_of<T>(_: T) {
    println!("{}", unsafe { std::intrinsics::type_name::<T>() })
}

Вывод будет следующим:

&bool
bool
&&bool
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...