Под капотом векторы в Rust возвращаются по ссылке или по значению? - PullRequest
0 голосов
/ 11 сентября 2018

Я пытаюсь изучить все тонкости памяти в Rust.Когда вектор создается внутри функции, а затем возвращается, возвращается ли ссылка или копируется весь вектор?

Пример:

use std::io;

fn line_to_ints() -> Vec<u32> {
    let mut line = String::new();

    io::stdin()
        .read_line(&mut line)
        .expect("Failed to read line");

    return line
        .split(" ")
        .map(|x| x.parse().expect("Not an integer!"))
        .collect();
}

Будет ли поведение возврата здесь также одинаковым длявсе другие не примитивные типы данных?

В отличие от Есть ли способ вернуть ссылку на переменную, созданную в функции? , я хотел бы узнать немного больше о том, что происходитпод капотом.Ответы на этот вопрос не дают ясности относительно того, создается ли вектор и затем копируется в новое местоположение, или возвращается владение указателем. Я понимаю, что векторы создаются в куче, поэтому я предполагаю, что указатель задействован.

1 Ответ

0 голосов
/ 11 сентября 2018

- возвращаемая ссылка

Нет.Этого не может быть, потому что ничего не может сослаться на после завершения функции.Это подробно описано в Есть ли способ вернуть ссылку на переменную, созданную в функции? .

- скопирован весь вектор

Да, но, вероятно, не так, как вы это имеете в виду.Vec - это , в основном , определяемый как

struct Vec<T> {
    capacity: usize,
    length: usize,
    data: *mut T,
}

Семантически эти 3 поля размером с указатель перемещаются из функции в вызывающую функцию.Элементы N, содержащиеся в векторе, не копируются.

В зависимости от реализации компилятор / оптимизатор может выбирать из большого количества хитростей:

  • Фактически копировать все три поля
  • Передача секретной изменяемой ссылки и прямая запись в нее функции
  • Встроенная функция, где она вызывается
  • Выполнение удаления мертвого кода и никогда не вызывать функцию в первую очередь
  • Вероятно, другие ...

Единственный способ узнать, что он выбирает, это посмотреть на ИК / сборку MIR / LLVM.

Willповедение возврата здесь также будет одинаковым для всех других не примитивных типов данных?

Да.Все типы данных Rust обрабатываются одинаково.Примитивные и не примитивные ничего не значат для семантики языка.

См. Также:

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