Спільні посилання

Посилання забезпечує доступ до іншого значення без отримання права власності на нього, і також називається "запозиченням". Спільні посилання доступні лише для читання, і дані, на які вони посилаються, не можуть бути змінені.

fn main() {
    let a = 'A';
    let b = 'B';
    let mut r: &char = &a;
    println!("r: {}", *r);
    r = &b;
    println!("r: {}", *r);
}

Спільне посилання на тип T має тип &T. Значення посилання робиться за допомогою оператора &. Оператор * "розіменовує" посилання, повертаючи його значення.

Rust статично забороняє висячі посилання:

fn x_axis(x: &i32) -> &(i32, i32) {
    let point = (*x, 0);
    return &point;
}
This slide should take about 10 minutes.
  • Посилання ніколи не можуть бути null у Rust, тому перевірка на null не є обов'язковою.

  • Кажуть, що посилання "позичає" значення, на яке воно посилається, і це гарна модель для слухачів, які не знайомі з вказівниками: код може використовувати посилання для доступу до значення, але все одно залишається "власністю" вихідної змінної. Більш детально про володіння буде розглянуто на третьому дні курсу.

  • Посилання реалізовано як вказівники, і ключовою перевагою є те, що вони можуть бути набагато меншими за об'єкт, на який вони вказують. Слухачі, знайомі з C або C++, розпізнають посилання як вказівники. У наступних частинах курсу буде розглянуто, як Rust запобігає помилкам, пов'язаним з безпекою пам'яті, які виникають при використанні сирих вказівників.

  • Rust не створює посилання автоматично - завжди потрібно використовувати &.

  • У деяких випадках Rust виконує автоматичне розіменування, зокрема під час виклику методів (спробуйте r.is_ascii()). Тут не потрібен оператор ->, як у C++.

  • У цьому прикладі r є мутабельним, тому його можна перепризначити (r = &b). Зверніть увагу, що це повторно зв'язує r, так що він посилається на щось інше. Це відрізняється від C++, де присвоювання посилання змінює значення, на яке воно посилається.

  • Спільне посилання не дозволяє змінювати значення, на яке воно посилається, навіть якщо це значення було змінним. Спробуйте *r = 'X'.

  • Rust відстежує час життя всіх посилань, щоб переконатися, що вони живуть достатньо довго. У безпечному Rust'і не може бути "висячих" посилань. Функція x_axis поверне посилання на point, але point буде звільнено, коли функція повернеться, тому це не буде скомпільовано.

  • Про запозичення ми поговоримо більше, коли дійдемо до володіння.