Почему захват по ссылке эквивалентен захвату ссылки по значению в Rust?

Выдержка из Поиск замыкания в Rust Хьюона Уилсона:

Захват полностью по значению также строго более общий, чем захват по ссылке: ссылочные типы являются первоклассными в Rust, поэтому захват по ссылке аналогичен захвату ссылки по значению. Таким образом, в отличие от C++, между захватом по ссылке и по значению нет принципиальной разницы, и анализ, который делает Rust, на самом деле не нужен: он просто облегчает жизнь программистам.

Я изо всех сил пытаюсь обдумать это. Если вы фиксируете ссылку по значению, не захватываете ли вы данные, хранящиеся в куче? Или это относится к значению указателя ссылки, которая находится в стеке?


person Paul Razvan Berg    schedule 07.12.2020    source источник


Ответы (2)


Или это относится к значению указателя ссылки, которая находится в стеке?

Да, иш.

В Rust ссылки овеществлены, это реальная вещь, которой вы манипулируете. Таким образом, когда вы захватываете ссылку по значению, вы захватываете саму ссылку (указатель, которым на самом деле является ссылка Rust), а не рефери (указатель).

Захват по ссылке в основном просто неявно создает ссылку и захватывает ее по значению.

person Masklinn    schedule 07.12.2020

Я думаю, что статья имеет в виду, что эффект почти эквивалентен. Неизменяемые ссылки реализуют признак копирования, из-за чего, когда вы захватите ссылку по значению, она будет скопирована. Таким образом, вы только что создали еще одну общую ссылку на те же данные.

fn as_ref(_x: &String) {}

fn as_mut(_x: &mut String) {}

fn main() {
    let mut x = String::from("hello world");
    let y = &x;

    let _ = move || {
        as_ref(y); // here you moved y but it
                   // basically created a copy
    };

    let z = y; // can be used later

    // The same cannot be done by mutable
    // refs because they don't
    // implement Copy trait
    
    let y = &mut x;

    let _ = move || {
        as_mut(y); // here you moved y and
                   // it cannot be used outside
    };

    // ERROR! Cannot be used again
    //let z = y;
}

Игровая площадка

person Mihir Luthra    schedule 07.12.2020