Запозичення значення
Як ми бачили раніше, замість того, щоб передавати право власності при виклику функції, ви можете дозволити функції позичити значення:
#[derive(Debug)] struct Point(i32, i32); fn add(p1: &Point, p2: &Point) -> Point { Point(p1.0 + p2.0, p1.1 + p2.1) } fn main() { let p1 = Point(3, 4); let p2 = Point(10, 20); let p3 = add(&p1, &p2); println!("{p1:?} + {p2:?} = {p3:?}"); }
- Функція
add
позичає дві точки та повертає нову точку. - Викликач зберігає право власності на вхідні дані.
Цей слайд є оглядом матеріалу про посилання з першого дня, дещо розширеного за рахунок включення аргументів функцій та значень, що повертаються.
Більше інформації для вивчення
Примітки щодо повернення стеку та вбудовування:
-
Продемонструйте, що повернення з
add
є дешевим, оскільки компілятор може виключити операцію копіювання, вбудовуючи виклик додавання в main. Змініть наведений вище код так, щоб він виводив адреси стеку, і запустіть його на Playground або перегляньте збірку в Godbolt. На рівні оптимізації "DEBUG" адреси мають змінитися, але вони залишаються незмінними під час переходу до налаштування "RELEASE":#[derive(Debug)] struct Point(i32, i32); fn add(p1: &Point, p2: &Point) -> Point { let p = Point(p1.0 + p2.0, p1.1 + p2.1); println!("&p.0: {:p}", &p.0); p } pub fn main() { let p1 = Point(3, 4); let p2 = Point(10, 20); let p3 = add(&p1, &p2); println!("&p3.0: {:p}", &p3.0); println!("{p1:?} + {p2:?} = {p3:?}"); }
-
Компілятор Rust може виконувати автоматичне вбудовування, яке можна вимкнути на рівні функції за допомогою
#[inline(never)]
. -
Якщо вимкнено, друкована адреса зміниться на всіх рівнях оптимізації. Дивлячись на Godbolt або Playground, можна побачити, що в цьому випадку повернення значення залежить від ABI, наприклад, на amd64 два i32, що складають точку, будуть повернуті у 2х регістрах (eax і edx).