22 октября 2021

πŸ›  Π’Π»Π°Π΄Π΅Π½ΠΈΠ΅ ΠΈ заимствованиС Π² Rust: Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎ ΠΎ Lifetime для Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΡ… ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΎΠΏΡ‹Ρ‚Π½Ρ‹Ρ…

Backend-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ со стаТСм Π² 15 Π»Π΅Ρ‚. УвлСкаюсь Rust.
Π’Π»Π°Π΄Π΅Π½ΠΈΠ΅ ΠΈ заимствованиС – ΠΊΠ»ΡŽΡ‡Π΅Π²Π°Ρ концСпция языка Rust ΠΈ Π΅Π³ΠΎ нСоспоримоС прСимущСство. ΠΠ΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ ΠΎΡΠ²ΠΎΠΈΡ‚ΡŒ эту ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΡŽ являСтся насущной для любого Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°, Π° ΠΊΠ»ΡŽΡ‡ΠΎΠΌ ΠΊ Π½Π΅ΠΉ станСт Lifetime. ΠŸΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΠΎΠ± этом Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎ.
πŸ›  Π’Π»Π°Π΄Π΅Π½ΠΈΠ΅ ΠΈ заимствованиС Π² Rust: Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎ ΠΎ Lifetime для Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΡ… ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΎΠΏΡ‹Ρ‚Π½Ρ‹Ρ…
Для ΠΊΠΎΠ³ΠΎ эта ΡΡ‚Π°Ρ‚ΡŒΡ
Для ΠΌΠ½ΠΎΠ³ΠΈΡ… программистов, ΠΏΡ€ΠΈΠ²Ρ‹ΠΊΡˆΠΈΡ… ΠΊ ΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Ρ‹ΠΌ состояниям Π΄Π°Π½Π½Ρ‹Ρ… Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π½ΠΎ-ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΎΠΉ ΡƒΠΏΠ°ΠΊΠΎΠ²ΠΊΠ΅, Rust становится настоящим ΠΎΡ‚ΠΊΡ€ΠΎΠ²Π΅Π½ΠΈΠ΅ΠΌ. НС ΡƒΠ΄ΠΈΠ²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ, вСдь Ρ‚ΡƒΡ‚ Π½Π΅Ρ‚ сборщика мусора, Π° Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ памяти Π΅ΡΡ‚ΡŒ. ИмСнно это ΠΈ Π΄Π΅Π»Π°Π΅Ρ‚ язык ΠΏΠΎ-настоящСму ΠΌΠΎΡ‰Π½Ρ‹ΠΌ, Π° Π΅Π³ΠΎ систСму Ρ‚ΠΈΠΏΠΎΠ² Π·ΡƒΠ±ΠΎΠ΄Ρ€ΠΎΠ±ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ-слоТной. Π›ΡŽΠ±ΠΎΠΉ Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΠΉ ΠΈΠ·ΡƒΡ‡Π°Ρ‚ΡŒ Rust программист Π² ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ Ρ‡ΠΈΡ‚Π°Π΅Ρ‚ Rust Book, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΡ‡Π΅Π½ΡŒ Ρ‚ΠΎΡ‡Π½ΠΎ ΠΏΠ΅Ρ€Π΅Π²Π΅Π΄Ρ‘Π½ Π½Π° русский язык. Π­Ρ‚ΠΎ ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹ΠΉ тСкст: слСдуя соврСмСнным трСбованиям ΠΊ ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΡŽ, ΠΎΠ½ создаСт Π²ΠΏΠ΅Ρ‡Π°Ρ‚Π»Π΅Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ всС достаточно просто. БлоТности Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‚ΡΡ Π²ΠΎ врСмя ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ. Borrow checker заставит ваш ΠΌΠΎΠ·Π³ Π²ΡΠΎΡΠ°Ρ‚ΡŒ вСсь ΠΎΡΡ‚Π°Π²ΡˆΠΈΠΉΡΡ Π² ΠΊΡ€ΠΎΠ²ΠΈ сахар, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΏΠΎΡ‡Π΅ΠΌΡƒ ΠΎΠ½ΠΎ Π½Π΅ компилируСтся.

Π—Π½Π°Ρ‡ΠΈΡ‚ Π»ΠΈ это, Ρ‡Ρ‚ΠΎ Π²Π°ΠΌ придСтся ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ слоТныС тСксты Π½Π° эту Ρ‚Π΅ΠΌΡƒ? Π‘ΠΊΠ°ΠΆΠ΅ΠΌ, ΠΊΠΎΠ³Π΄Π°-Π½ΠΈΠ±ΡƒΠ΄ΡŒ – Π΄Π°. Пока эту Π·Π°Π΄Π°Ρ‡Ρƒ стараСтся Ρ€Π΅ΡˆΠΈΡ‚ΡŒ наша ΡΡ‚Π°Ρ‚ΡŒΡ, которая Π²ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ… написана ΠΏΠΎ-русски, Π° Π²ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ… содСрТит Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ†ΠΈΡŽ ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΉ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ, ΠΏΡ€ΠΈΠ·Π²Π°Π½Π½ΡƒΡŽ ΡΠ½ΠΈΠ·ΠΈΡ‚ΡŒ ΡΡ‚Π°Π²ΡˆΡƒΡŽ ΠΌΠ΅ΠΌΠΎΠΌ Β«ΠšΡ€ΡƒΡ‚ΡƒΡŽ ΠΊΡ€ΠΈΠ²ΡƒΡŽ обучСния» (Steep learning curve). Для понимания Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ хотя Π±Ρ‹ Π² ΠΎΠ±Ρ‰ΠΈΡ… Ρ‡Π΅Ρ€Ρ‚Π°Ρ… ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ сСбС, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ ΠΊΡƒΡ‡Π° ΠΈ стСк ΠΈ Π·Π°Ρ‡Π΅ΠΌ ΠΎΠ½ΠΈ Π½ΡƒΠΆΠ½Ρ‹. Π’ Ρ‚ΠΎΠΉ ΠΈΠ»ΠΈ ΠΈΠ½ΠΎΠΉ стСпСни этот вопрос Ρ€Π°ΡΠΊΡ€Ρ‹Π²Π°ΡŽΡ‚ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Ρ‹ ΠΏΠΎ Ρ€Π°Π·Π½Ρ‹ΠΌ языкам программирования. Π’Π°ΠΊΠΆΠ΅ ΠΎΡ‡Π΅Π½ΡŒ Π²Π°ΠΆΠ½ΠΎ Π²Ρ‹ΡƒΡ‡ΠΈΡ‚ΡŒ Π±ΡƒΠΊΠ²Π°Π»ΡŒΠ½ΠΎ Ρ‚Ρ€ΠΈ ΠΏΡƒΠ½ΠΊΡ‚Π° ΠΏΡ€Π°Π²ΠΈΠ» владСния.

Π’ Ρ‡Π΅ΠΌ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°?

Π­Ρ‚ΠΎ стандартноС ΠΏΡ€ΠΎΠ΄Π°ΡŽΡ‰Π΅Π΅ язык объяснСниС. ΠŸΠΎΡΠ²ΡΡ‰Π΅Π½Π½Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π΅Π³ΠΎ ΠΏΡ€ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ.

Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½Π°Ρ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° «опасных» языков C ΠΈ C++ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ управляСм Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π² ΠΊΡƒΡ‡Π΅, Π½ΠΎ Π½Π΅ ΠΈΠΌΠ΅Π΅ΠΌ способа ТСстко ΡΠ²ΡΠ·Π°Ρ‚ΡŒ эти Π΄Π°Π½Π½Ρ‹Π΅ с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ Π² стСкС, Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… управляСт компилятор. Π—Π½Π°Ρ‡ΠΈΡ‚ ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π±Ρ‹Ρ‚ΡŒ ΡƒΠ²Π΅Ρ€Π΅Π½Π½Ρ‹ΠΌΠΈ Π² ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠΈ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ. ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ΠΎΡ‡Π΅Π½ΡŒ просто.

Π•Ρ‰Ρ‘ большС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° усугубляСтся ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΎΡΡ‚ΡŒΡŽ ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½Ρ‹ΠΉ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π² Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… экзСмплярах ΠΈΠΌΠ΅Π΅Ρ‚ прямой доступ ΠΊ ΠΎΠ±Ρ‰Π΅ΠΉ для всСх ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² памяти. Π’ΡƒΡ‚ Π²Π°ΠΆΠ½ΠΎ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ запросы Π½Π° ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡŽ Π΄Π°Π½Π½Ρ‹Ρ… Π² памяти ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ (с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния процСссора) Π½Π΅ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹ΠΌΠΈ, Π° Π·Π½Π°Ρ‡ΠΈΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒΡΡ нСсколько инструкций для ΠΎΠ΄Π½ΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. Если ΠΆΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π΄Π²Π° ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ, Ρ‚ΠΎ инструкции процСссора, скаТСм, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅ΡˆΠΈΠ²Π°ΡŽΡ‚ΡΡ, ΠΈ получаСтся Π±Π°Ρ€Π΄Π°ΠΊ, Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΡ‹ΠΉ Π³ΠΎΠ½ΠΊΠΎΠΉ Π΄Π°Π½Π½Ρ‹Ρ… (Data Races), Ρ‡Ρ‚ΠΎ Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ являСтся Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ (Undefined Behaviour, Π΄Π°Π»Π΅Π΅ UB). ΠžΡ‚Π»Π°Π΄ΠΊΠ° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π² поисках ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹ UB – Ρ‡Ρ€Π΅Π·Π²Ρ‹Ρ‡Π°ΠΉΠ½ΠΎ Ρ‚Ρ€ΡƒΠ΄ΠΎΠ΅ΠΌΠΊΠΈΠΉ процСсс.

Π Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Rust поняли ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹ этих ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠ»ΠΈ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ Ρ…ΠΎΡ€ΠΎΡˆΠΈΡ… статичСских Π°Π½Π°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠ² ΠΊΠΎΠ΄Π° Π½Π° C/C++ (Π½ΠΎ это Π½Π΅ Ρ‚ΠΎΡ‡Π½ΠΎ) для создания языка, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎ своСй сСмантикС Π½Π΅ позволяСт программисту ΠΎΡ‚ΡΡ‚Ρ€Π΅Π»ΠΈΡ‚ΡŒ сСбС Π½ΠΎΠ³Ρƒ. ΠŸΡ€ΠΈ этом Rust Π½Π΅ создаСт прослойку ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠΎΠ΄ΠΎΠΌ ΠΈ ΠΆΠ΅Π»Π΅Π·ΠΎΠΌ Π² Π²ΠΈΠ΄Π΅ ΠΈΠ·Π±Ρ‹Ρ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ runtime с garbage collector.

Бсылки

Π’ Ρ†Π΅Π»ΠΎΠΌ &ссылки/*ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½ΡƒΠΆΠ½Ρ‹ ΠΊΠΎΠ³Π΄Π° Π΄Π°Π½Π½Ρ‹Π΅: находятся Π² ΠΊΡƒΡ‡Π΅ (ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Π°Ρ Ρ‚Π΅ΠΌΠ°), ΠΈΠ»ΠΈ просто Ρ€Π°Π΄ΠΈ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ ΠΈΠ·Π±Ρ‹Ρ‚ΠΎΡ‡Π½ΠΎΠ΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Ρ… Π² стСкС.

Π’ Rust Π΅ΡΡ‚ΡŒ Ρ€ΠΎΠ²Π½ΠΎ Π΄Π²Π° Ρ‚ΠΈΠΏΠ° ссылок (ΠΏΡ€ΠΎ сырыС ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ):

  • Бсылки Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ (shared reference): &lnk_name – позволяСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅.
  • Π˜Π·ΠΌΠ΅Π½ΡΠ΅ΠΌΡ‹Π΅ (ΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Ρ‹Π΅) ссылки: &mut lnk_name – позволяСт ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅.

Бсылки ΠΏΠΎΠ΄Ρ‡ΠΈΠ½ΡΡŽΡ‚ΡΡ Π΄Π²ΡƒΠΌ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ, Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΡ‹ΠΌ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌΠΈ заимствования:

  • Бсылки Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΆΠΈΡ‚ΡŒ дольшС Ρ‡Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ½ΠΈ ΡΡΡ‹Π»Π°ΡŽΡ‚ΡΡ (Rust Book описываСт это Ρ‚Π°ΠΊ: «всС ссылки Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈΒ»).
  • ΠœΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Π°Ρ ссылка Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Π° ΠΈΠ»ΠΈ, цитируя Rust Book: Β«Π² ΠΎΠ΄ΠΈΠ½ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π»ΠΈΠ±ΠΎ ΠΎΠ΄Π½Π° измСняСмая ссылочная пСрСмСнная, Π»ΠΈΠ±ΠΎ любоС количСство нСизмСняСмых ссылочных ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…Β». ЗабСгая Π²ΠΏΠ΅Ρ€Π΅Π΄: Π½Π° ΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Ρ‹Ρ… ссылках Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½ алиасинг. Англицизм Ρ‚ΡƒΡ‚ Π½ΡƒΠΆΠ΅Π½ для описания ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ эффСкта Π²Π½Π΅Π·Π°ΠΏΠ½ΠΎΠ³ΠΎ измСнСния значСния ΠΏΠΎΠ΄ ссылкой. Π­Ρ‚ΠΎ справСдливо Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для области видимости, Π½ΠΎ ΠΈ для всСй выполняСмой Π²Π΅Ρ‚ΠΊΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Π‘ΠΊΠ°ΠΆΠ΅ΠΌ большС, ΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Π°Ρ ссылка Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΠΉ ΠΈ Π² Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠ°Ρ…, Ρ‡Ρ‚ΠΎ достигаСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Mutex.

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ Lifetime?

Вспомним ΠΏΠ΅Ρ€Π²ΠΎΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ ссылок: Π΄Π°Π½Π½Ρ‹Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΆΠΈΡ‚ΡŒ дольшС Ρ‡Π΅ΠΌ ссылки Π½Π° Π½ΠΈΡ…, ΠΈ ΠΈΠΌΠ΅Π½Π½ΠΎ эту Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡŽ Π΄Π°Π΅Ρ‚ язык Rust с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Lifetime.

Π›ΡŽΠ±Π°Ρ пСрСмСнная – это ΠΏΠ°ΠΌΡΡ‚ΡŒ Π½Π° стСкС. Бсылка Π½Π° Π΄Ρ€ΡƒΠ³ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ (ΠΈΠ»ΠΈ Π½Π° Π΄Π°Π½Π½Ρ‹Π΅ Π² ΠΊΡƒΡ‡Π΅) – Ρ‚ΠΎΠΆΠ΅ пСрСмСнная Π² стСкС. Если ссылка ΠΏΡ€ΠΎΠΆΠΈΠ²Π΅Ρ‚ дольшС Ρ‡Π΅ΠΌ сами Π΄Π°Π½Π½Ρ‹Π΅, Ρ‚ΠΎ ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒΡΡ Ρ‡Π΅Ρ€Π΅Π· Π½Π΅Ρ‘ (Ρ€Π°Π·Ρ‹ΠΌΠ΅Π½ΠΎΠ²Π°Ρ‚ΡŒ), ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ освобоТдСнной памяти – классичСская ошибка сСгмСнтирования.
Lifetime – имСнованная ΠΎΠ±Π»Π°ΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ссылки Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π±ΡƒΠ΄ΡƒΡ‚ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ. Π­Ρ‚ΠΈ области ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‡Π΅Π½ΡŒ слоТными, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ½ΠΈ соотносятся с Π²Π΅Ρ‚Π²Π»Π΅Π½ΠΈΠ΅ΠΌ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.
Π”Π°Π΄ΠΈΠΌ Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅, цитируя Rustomonicon.

Π’ΠΎΡ‚ прямо Ρ‚Π°ΠΊ. НС врСмя – ΠΎΠ±Π»Π°ΡΡ‚ΡŒ ΠΊΠΎΠ΄Π°. Для нас это абстрактноС врСмя, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ области ΠΊΠΎΠ΄Π° Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ. Lifetime – это ΠΊΠ°ΠΊ имя самой области, Ρ‚Π°ΠΊ ΠΈ ΠΌΠ΅Ρ‚ΠΊΠ° для ссылки Π½Π° эту ΠΎΠ±Π»Π°ΡΡ‚ΡŒ. Π—Π°ΠΏΠΎΠΌΠ½ΠΈΠΌ это.

НачнСм с Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ врСмя ΠΆΠΈΠ·Π½ΠΈ Π΅ΡΡ‚ΡŒ Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Rust. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ Π² C-ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹Ρ… языках врСмя ΠΆΠΈΠ·Π½ΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΎ функциями (экспСрты ΠΏΠΎ стандарту C/C++ ΠΏΠΎΠΏΡ€Π°Π²ΡŒΡ‚Π΅, Ссли Ρ‡Ρ‚ΠΎ). И Π² Rust ΠΈ Π² Π‘/C++ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ видимости ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… синтаксисом Π±Π»ΠΎΠΊΠΎΠ² β€œ{...}”, ΠΎΠ΄Π½Π°ΠΊΠΎ Π² Rust Π±Π»ΠΎΠΊ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ опрСдСляСт ΠΊΠ°ΠΊ Β«Π΄ΠΎΠ»Π³ΠΎΒ» пСрСмСнная ΠΏΡ€ΠΎΠΆΠΈΠ²Π΅Ρ‚ Π½Π° стСкС, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ C/C++, Π³Π΄Π΅ Π±Π»ΠΎΠΊ слуТит для сСмантичСского ограничСния доступа ΠΊ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ.

Π’ΠΎΠ·ΡŒΠΌΡ‘ΠΌ простой ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

        fn main() {
   let num_ref;
   {
       let num = 4;
       num_ref = #
   } // Ρ‚ΡƒΡ‚ пСрСмСнная num Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ΅Π½Π°, выйдя Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Ρ‹ Π±Π»ΠΎΠΊΠ°.
   // Однако num_ref ссылаСтся Π½Π° Π΅Ρ‘ адрСс,
   // Π½ΠΎ ΠΏΠΎΠΊΠ° всС Π² порядкС, Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ висящСй ссылки Π½Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°
 
   // Π° Π²ΠΎΡ‚ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° Ρ€Π°Π·Ρ‹ΠΌΠ΅Π½ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΡƒΡŽ ссылку - ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°, Ρ‚.Π΅. UB
   println!("say number {}", *num_ref);
}
    

ΠŸΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ эту ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ компилятор выдаст ΠΎΡˆΠΈΠ±ΠΊΡƒ:

πŸ›  Π’Π»Π°Π΄Π΅Π½ΠΈΠ΅ ΠΈ заимствованиС Π² Rust: Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎ ΠΎ Lifetime для Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΡ… ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΎΠΏΡ‹Ρ‚Π½Ρ‹Ρ…

ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ ΡΠΌΠΎΠ΄Π΅Π»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π½Π° C Ρ‡Ρ‚ΠΎ ΠΌΠΎΠ³Π»ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒΡΡ, Ссли Π±Ρ‹ Rust нас Π½Π΅ Π·Π°Ρ‰ΠΈΡ‚ΠΈΠ».

Π’ C Π±Π»ΠΎΠΊΠΈ ΠΊΠΎΠ΄Π° Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΈΠ½Π°Ρ‡Π΅. Вакая ΠΆΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π½Π° C Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ Π² силу Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Ρƒ C Π½Π΅Ρ‚ потрСбности ΠΏΡ€ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π΅ ΠΈΠ· Π±Π»ΠΎΠΊΠ° Π²Ρ‹ΠΊΠΈΠ½ΡƒΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· стСка. ΠŸΠΎΡ‚ΠΎΠΌΡƒ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π½Π° C для ограничСния области видимости ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ. Π­Ρ‚ΠΎ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ Π»ΠΈΠΊΠ²ΠΈΠ΄Π°Ρ†ΠΈΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π² стСкС ΠΈ воспроизводит ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Rust ΠΏΡ€ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π΅ Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Ρ‹ Π±Π»ΠΎΠΊΠ°.

        #include "stdio.h"
 
int* get_num_ptr() {
 int num = 4;
 return #
}
 
int main() {
 int* num_ref = get_num_ptr();
 printf("say num: %d", *num_ref);
}

    

Π‘ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠ΅ΠΌ ΠΈ исполним:

        gcc src/bin/lifetime_too_short.c -o lifetime_too_short_c && ./lifetime_too_short_c
    

ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

πŸ›  Π’Π»Π°Π΄Π΅Π½ΠΈΠ΅ ΠΈ заимствованиС Π² Rust: Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎ ΠΎ Lifetime для Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΡ… ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΎΠΏΡ‹Ρ‚Π½Ρ‹Ρ…

Borrow-checker просто Π½Π΅ позволяСт Π½Π°ΠΌ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΏΠΎΠ΄ΠΎΠ±Π½ΡƒΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π½Π° Rust. GCC Π²ΠΈΠ΄ΠΈΡ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ, Π½ΠΎ всС Ρ€Π°Π²Π½ΠΎ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΊΠΎΠ΄. Наш ΠΏΡ€ΠΈΠΌΠ΅Ρ€ слишком прост, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ пропустил ΠΎΡˆΠΈΠ±ΠΊΡƒ (clang ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ с Ρ‚Π°ΠΊΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ ΠΈ вовсС ΡƒΠ±Π΅Ρ€Π΅ΠΆΠ΅Ρ‚ ΠΎΡ‚ ошибки сСгмСнтирования), ΠΎΠ΄Π½Π°ΠΊΠΎ C ΠΈ C++ Π½ΠΈΠΊΠ°ΠΊ Π½Π΅ Π·Π°Ρ‰ΠΈΡ‰Π°ΡŽΡ‚ ΠΎΡ‚ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ³ΠΎ с Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния сСмантики языка. Π’ простых случаях ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚ΡŒΡΡ Π½Π° компилятор, Π½ΠΎ Π½Π΅Ρ‚ языковых ΠΌΠ΅Ρ…Π°Π½ΠΈΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠ±Π΅Ρ€Π΅Π³ΡƒΡ‚ нас ΠΎΡ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π² ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ΅. На ΠΏΠΎΠΌΠΎΡ‰ΡŒ ΠΏΡ€ΠΈΠ΄Ρ‘Ρ‚ стандартная Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° C++, хотя Π΄Π°ΠΆΠ΅ с Π½Π΅ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚ΡΡ‚Ρ€Π΅Π»ΠΈΡ‚ΡŒ сСбС Ρ‡Ρ‚ΠΎ ΡƒΠ³ΠΎΠ΄Π½ΠΎ.

Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΠΉΡ‚ΠΈ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° C/C++ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°Β».

ΠœΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Ρ‹Π΅ ссылки ΠΈ модСль алиасинга

Π­Ρ‚ΠΎΡ‚ вопрос ΠΌΡ‹ рассмотрим Π² контСкстС ΠΎΠ΄Π½ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ исполнСния Π±Π΅Π· ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π½ΠΈΠΉ. АсинхронноС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΡ‚ Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Ρ‹ Ρ‚Π΅ΠΌΡ‹.

Π’ΠΎΠ·ΡŒΠΌΠ΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ· Rust Book:

        fn big_problem() {
 let mut s = String::from("hello");
 let r1 = &s; // no problem
 let r2 = &s; // no problem
 let r3 = &mut s; // BIG PROBLEM
 println!("{}, {}, and {}", r1, r2, r3);
}

    

Π’ΠΈΠ΄Π½ΠΎ Ρ‡Ρ‚ΠΎ это прямоС Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅ ΠΏΡ€Π°Π²ΠΈΠ» заимствования. Rust Book вСсьма Π»Π°ΠΊΠΎΠ½ΠΈΡ‡Π½ΠΎ описываСт Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ ΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Ρ‹ΠΉ алиасинг Ρ„Ρ€Π°Π·ΠΎΠΉ: Β«ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ нСизмСняСмой ссылки Π½Π΅ ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‚ Π²Π½Π΅Π·Π°ΠΏΠ½ΠΎΠ³ΠΎ измСнСния значСния, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ½Π° ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚!Β» Однако Π½Π° этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ Π½Π΅ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ, ΠΏΠΎΡ‡Π΅ΠΌΡƒ это ΠΏΠ»ΠΎΡ…ΠΎ.

Π”Π°Π²Π°ΠΉΡ‚Π΅ Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΊΠΎΠ΄, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ это эффСкт Π² Π³Π»Π°Π·Π° Π½Π΅ бросаСтся, Π½ΠΎ ΠΏΠΎΠΊΠ°ΠΆΠ΅Ρ‚, ΠΏΠΎΡ‡Π΅ΠΌΡƒ ΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Π°Ρ ссылка Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΠΉ:

        fn compute(input: &u32, output: &mut u32) {
 if *input > 10 {
     *output = 1;
 }
 if *input > 5 {
     *output *= 2;
 }
 // ΠΏΠΎΠΌΠ½ΠΈΡ‚Π΅ Ρ‡Ρ‚ΠΎ пСрСмСнная `output` == `2` Ссли `input > 10`
}

    

ΠŸΡ€ΠΈ Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎΠΌ Π΅Ρ‘ использовании Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΌ – Π² output Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΎ число 2:

        let input = 20;
let mut output = 0;
compute(&input, &mut output); // Π² `output` ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚ 2
    

Однако Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ compute() Π΅ΡΡ‚ΡŒ ΠΎΠ΄ΠΈΠ½ интСрСсный эффСкт. Π§Ρ‚ΠΎ Ссли ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΄ΠΈΠΌ Π² качСствС ΠΎΠ±ΠΎΠΈΡ… Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ссылки Π½Π° ΠΎΠ΄ΠΈΠ½ ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ кусок памяти?

        let mut num = 20;
compute(&num, &mut num);
    
Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ послС ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ Π±Π»ΠΎΠΊΠ° if Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ input измСнится ΠΈ Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π±Π»ΠΎΠΊ if просто Π½Π΅ сработаСт, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ input Ρ‚ΠΎΠΆΠ΅ измСнился ΠΈ содСрТит Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΌΠ΅Π½Π΅Π΅ 5. Π­Ρ‚ΠΎ ΠΈ Π±Ρ‹Π»ΠΎ Π½Π°Π·Π²Π°Π½ΠΎ Π² Rust Book Π²Π½Π΅Π·Π°ΠΏΠ½Ρ‹ΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ значСния, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ нашС Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΠΏΡ€ΠΈΠΊΠΎΠ²Π°Π½ΠΎ ΠΊ ΠΈΠΌΠ΅Π½Π°ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΈ ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ эти Π΄Π°Π½Π½Ρ‹Π΅ Ρ€Π°Π·Π½Ρ‹Π΅.

Пока здСсь слоТно Ρ€Π°Π·Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ совсСм Ρ€Π°Π·Ρ€ΡƒΡˆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅, Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, Π΅ΡΡ‚ΡŒ Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΌΠΎΠ³ΡƒΡ‚ ΡΠΊΡΠΏΠ»ΡƒΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π²ΠΎ Π±Π»Π°Π³ΠΎ (Π½ΠΎ это Π½Π΅ Ρ‚ΠΎΡ‡Π½ΠΎ). Для нас Π²Π°ΠΆΠ΅Π½ Ρ„Π°ΠΊΡ‚, Ρ‡Ρ‚ΠΎ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ языков с ΠΈΡ… Π»ΠΈΠ±Π΅Ρ€Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠΌ Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°ΡŽΡ‚ ΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Ρ‹ΠΉ алиасинг.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΈΡ… Π±Π»ΠΎΠΊΠΎΠ² Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΌΠ½ΠΎΠ³ΠΎ ΠΈ Π΅ΡΡ‚ΡŒ ΠΌΠ½ΠΎΠ³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ€Π°ΡΡΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽΡ‚ Π½Π° ΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Ρ‹ΠΉ алиасинг. Π‘ΠΊΠΎΡ€Π΅Π΅ всСго вмСстС с Π²Π½Π΅Π·Π°ΠΏΠ½Ρ‹ΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ нСизмСняСмых ссылок Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ Π²Π½Π΅Π·Π°ΠΏΠ½Ρ‹ΠΉ Π½Π΅ΠΎΠΆΠΈΠ΄Π°Π½Π½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚.

Rust Ρ‚Π°ΠΊ Π΄Π΅Π»Π°Ρ‚ΡŒ Π½Π΅ позволяСт ΠΈ пытаСтся ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ:

  • ΡΠΎΡ…Ρ€Π°Π½ΠΈΡ‚ΡŒ значСния Π² рСгистрах процСссора, ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€Π΄ΠΈΠ² отсутствиС ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΉ Ρ‡Π΅Ρ€Π΅Π· ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ;
  • ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ ΠΏΠ°ΠΌΡΡ‚ΡŒ Π½Π΅ Π±Ρ‹Π»Π° пСрСзаписана ΠΏΠ΅Ρ€Π΅Π΄ Π΅Ρ‘ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ΠΌ;
  • ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ ΠΏΠ°ΠΌΡΡ‚ΡŒ Π½Π΅ Π±Ρ‹Π»Π° ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½Π° ΠΏΠ΅Ρ€Π΅Π΄ записью;
  • ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΡƒΠΏΠΎΡ€ΡΠ΄ΠΎΡ‡ΠΈΡ‚ΡŒ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ ΠΈ запись, Π½Π΅ боясь Ρ‡Ρ‚ΠΎ значСния зависят Π΄Ρ€ΡƒΠ³ ΠΎΡ‚ Π΄Ρ€ΡƒΠ³Π°.

ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€ ΠΏΠΎΠΆΠ΅Π»Π°Π΅Ρ‚ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΊΠΎΠ΄ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Ρ€Π°Π·ΠΈΡ‚ΡŒ Ρ‚Π°ΠΊ:

        fn compute_on_stack(input: &u32, output: &mut u32) {
   let mut cache = *output;
   if *input > 10 {
     cache = 1;
   }
   if *input > 5 {
       cache *= 2;
   }
   *output = cache;
}
    
Rust ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ΡŒ сСбС Ρ‚Π°ΠΊΡƒΡŽ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΡŽ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Ρ‚ΠΎΡ‡Π½ΠΎ Π·Π½Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ input ΠΈ output ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ Π½Π° Ρ€Π°Π·Π½Ρ‹Π΅ значСния, ΠΏΠΎΡ‚ΠΎΠΌΡƒ ΠΌΠΎΠΆΠ½ΠΎ всС разымСнования Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π½Π° ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ ΠΊΠΎΠΏΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ… Π² локальном кСшС Π² рСгистрС. Π›ΠΈΠ±Π΅Ρ€Π°Π»ΡŒΠ½Ρ‹Π΅ C ΠΈ C++ Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ΡŒ сСбС Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚: Π²Π΄Ρ€ΡƒΠ³ программист рассчитываСт Π½Π° ΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Ρ‹ΠΉ алиасинг.

Lifetime ΠΊΠ°ΠΊ Π±Π»ΠΎΠΊ ΠΈ ΠΊΠ°ΠΊ Ρ‚ΠΈΠΏ

Как Π±Ρ‹Π»ΠΎ сказано Π²Ρ‹ΡˆΠ΅, lifetime – это ΠΎΠ±Π»Π°ΡΡ‚ΡŒ ΠΊΠΎΠ΄Π°, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΆΠΈΠ²Π΅Ρ‚ пСрСмСнная/Π΄Π°Π½Π½Ρ‹Π΅ ΠΈ эти области компилятор Π΄ΠΎΠ»ΠΆΠ΅Π½ Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ ограничСния ΠΈ Π²Ρ‹ΡΠ²ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΆΠΈΠ·Π½ΠΈ. Π’ Rust Π² night-сборках Π΄Π°ΠΆΠ΅ Π΅ΡΡ‚ΡŒ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ синтаксис, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ lifetime-ΠΌΠ΅Ρ‚ΠΊΠΈ Π² Π±Π»ΠΎΠΊΠ°Ρ… явным ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ. Π­Ρ‚ΠΎΡ‚ синтаксис ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ Π½Π°ΠΌ Β«Ρ€Π°ΡΡΠ°Ρ…Π°Ρ€ΠΈΠ²Π°Ρ‚ΡŒΒ» исходный ΠΊΠΎΠ΄ Π² прСдставлСниС, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ компилятор Π² ΠΈΡ‚ΠΎΠ³Π΅.

НапримСр, этот ΠΊΠΎΠ΄:

        let x = 0;
let y = &x;
let z = &y;
    

ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Ρ€Π°Π·ΠΈΡ‚ΡŒ Ρ‚Π°ΠΊ:

        'a: {
   let x: i32 = 0;
   'b: {
       let y: &'b i32 = &'b x;
       'c: {
           let z: &'c &'b i32 = &'c y;
       }
   }
}
    

Lifetime всСгда указываСтся Ρ‡Π΅Ρ€Π΅Π· апостроф. Π‘Π°ΠΌΠ° ΠΌΠ΅Ρ‚ΠΊΠ° Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ Π½Π°ΠΌ ΠΎΠ± ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Ρ€Π°Π·ΠΌΠ΅Ρ€Π°Ρ… lifetime (Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ β€˜static). Для нас имя Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΆΠΈΠ·Π½ΠΈ слуТит Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈΠ·Π½Π°ΠΊΠΎΠΌ равСнства ΠΈΠ»ΠΈ нСравСнства, ΠΎΡΡ‚Π°Π»ΡŒΠ½ΠΎΠ΅ – Π·Π°Π±ΠΎΡ‚Π° компилятора. Однако Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΡΡ‚ΡŒ Π±Π»ΠΎΠΊΠΎΠ² явно ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊΠΎΠΉ lifetime Π΄Π»ΠΈΠ½Π½Π΅Π΅.

Как Π²ΠΈΠ΄Π½ΠΎ ΠΈΠ· этого ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°, созданиС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°Π΅Ρ‚ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ Π±Π»ΠΎΠΊ с Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΈΠΌ lifetime. ΠŸΠΎΡ€ΡΠ΄ΠΎΠΊ создания ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Π² стСкС Π²Π°ΠΆΠ΅Π½ для соблюдСния ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ порядка ΠΈΡ… уничтоТСния. ΠŸΠΎΡ‚ΠΎΠΌΡƒ lifetime для ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΊΠΎΠ΄Π° Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π²Π΅Π΄Π΅Π½Ρ‹ нСсколько ΠΈΠ½Π°Ρ‡Π΅:

        let x = 0;
let z;
let y = &x;
z = y;
    

ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° ссылки Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Ρ‹ scope заставит Rust вывСсти Π±ΠΎΠ»Π΅Π΅ Π΄Π»ΠΈΠ½Π½Ρ‹Π΅ lifetime:

        'a: {
    let x: i32 = 0;
    'b: {
        let z: &'b i32;
        'c: {
            // Для &y ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ 'b вмСсто 'c
            // ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ эта ссылка ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π°
            // Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΈΠ· scopa-Π° 'b
            let y: &'b i32 = &'b x;
            z = y;
        }
    }
  }
    

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ структуры ΠΌΠΎΠ³ΡƒΡ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ ссылки, ΠΈ Ρ‚ΠΎΠ³Π΄Π° ΠΈΡ… сигнатуры ΠΏΡ€ΠΈΠΎΠ±Ρ€Π΅Ρ‚ΡƒΡ‚ Π³Π΅Π½Π΅Ρ€ΠΈΡ‡Π½Ρ‹ΠΉ Π²ΠΈΠ΄. Имя lifetime Π² Ρ‚Π°ΠΊΠΎΠΌ случаС являСтся Π½Π΅ΠΎΡ‚ΡŠΠ΅ΠΌΠ»Π΅ΠΌΡ‹ΠΌ Π²Ρ…ΠΎΠ΄Π½Ρ‹ΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠ° ΠΊΠ°ΠΊ ΠΈ Ρ‚ΠΈΠΏΠΎΠ²Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€. Π”Π°ΠΆΠ΅ Ссли ΠΌΡ‹ Π½Π΅ Π±ΡƒΠ΄Π΅ΠΌ ΠΏΡ€ΠΎΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€(Ρ‹) lifetime явно, ΠΎΠ½ΠΈ Π² любом случаС Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π²Π΅Π΄Π΅Π½Ρ‹ компилятором сразу послС появлСния Π² сигнатурС символа β€œ&”.

        fn as_str(data: &u32) -> &str {
   let s = format!("{}", data);
   &s
}
    

МоТно Π²Ρ‹Ρ€Π°Π·ΠΈΡ‚ΡŒ Ρ‚Π°ΠΊ:

        fn as_str<'a>(data: &'a u32) -> &'a str {
   'b: {
       let s = format!("{}", data);
       return &'a s;
   }
}
    
πŸ›  Π’Π»Π°Π΄Π΅Π½ΠΈΠ΅ ΠΈ заимствованиС Π² Rust: Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎ ΠΎ Lifetime для Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΡ… ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΎΠΏΡ‹Ρ‚Π½Ρ‹Ρ…

Вопрос ΠΏΠΎΡ‡Π΅ΠΌΡƒ функция Π΄ΠΎΠ»ΠΆΠ½Π° Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ссылку с lifetime Π½Π΅ мСньшим Ρ‡Π΅ΠΌ входящий, Π² Ρ†Π΅Π»ΠΎΠΌ, Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ ΡƒΠΆΠ΅ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹ΠΌ (ΠΌΡ‹ Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ Π΅Π³ΠΎ Π² дСталях). ЕстСствСнно, Π΄Π°Π½Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ‚Π°ΠΊ:

        fn to_string(data: &u32) -> String {
	format!("{}", data)
}
    
ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ String Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ссылки Π±ΡƒΠ΄Π΅Ρ‚ Π½Π΅ Π·Π°ΠΈΠΌΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒΡΡ, Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Ρ‚ΡŒΡΡ, ΠΏΠΎ сути это ΡƒΠΌΠ½Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ: Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Π±Π΅Π· создания ссылки, Π° сама строчка Π±ΡƒΠ΄Π΅Ρ‚ Π»Π΅ΠΆΠ°Ρ‚ΡŒ Π² ΠΊΡƒΡ‡Π΅.

ΠŸΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ Β«Ρ€Π°ΡΡΠ°Ρ…Π°Ρ€ΠΈΡ‚ΡŒΒ» Π΅Ρ‰Ρ‘ ΠΎΠ΄ΠΈΠ½ кусок ΠΊΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΡ‚ΠΎΠ±Ρ€Π°Π·ΠΈΡ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ ΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ алиасинга:

        let mut data = vec![1, 2, 3];
let x = &data[0];
data.push(4);
println!("{}", x);
    
ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ x – ссылка Π½Π° Ρ‡Π°ΡΡ‚ΡŒ Π²Π΅ΠΊΡ‚ΠΎΡ€Π°. Π’Π°ΠΊ ΠΊΠ°ΠΊ Π²Π΅ΠΊΡ‚ΠΎΡ€ – это ΡƒΠΌΠ½Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ, Ρ‚ΠΎ ΠΏΡ€ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ элСмСнта Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Π² ΠΊΡƒΡ‡Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ пСрСраспрСдСлСно Π²Π½Π΅ зависимости ΠΎΡ‚ нас ΠΈ всС ссылки Π½Π° старыС Π΄Π°Π½Π½Ρ‹Π΅ станут Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ (ошибка сСгмСнтирования ΠΈ/ΠΈΠ»ΠΈ UB). Однако компилятору Π½Π΅ Π½Π°Π΄ΠΎ Π½ΠΈΡ‡Π΅Π³ΠΎ Π·Π½Π°Ρ‚ΡŒ ΠΏΡ€ΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ x являСтся ссылкой Π½Π° Ρ‡Π°ΡΡ‚ΡŒ Π²Π΅ΠΊΡ‚ΠΎΡ€Π° ΠΈΠ»ΠΈ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ Π²Π΅ΠΊΡ‚ΠΎΡ€, ΠΈ ΠΊΠ°ΠΊ ΠΎΠ½ ΠΎΠΏΠ΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π² ΠΊΡƒΡ‡Π΅. ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€Ρƒ достаточно Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ заимствования.

ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€ Π²Ρ‹Π²Π΅Π΄Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ сразу Π²ΠΈΠ΄Π½ΠΎ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ с lifetime:

        'a: {
    let mut data: Vec<i32> = vec![1, 2, 3];
    'b: {
        // для ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ x выводится lifetime 'b
        // (Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π² этом scope-Π΅ происходит
        // ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ x Π² println!)
        let x: &'b i32 = Index::index::<'b>(&'b data, 0);
        'c: {
            Vec::push(&'c mut data, 4);
        }
        println!("{}", x);
    }
}
    

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Rust Π²ΠΈΠ΄ΠΈΡ‚, Ρ‡Ρ‚ΠΎ x Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΏΡ€ΠΎΠΆΠΈΡ‚ΡŒ врСмя β€˜b, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π½Π°ΠΏΠ΅Ρ‡Π°Ρ‚Π°Π½Π½Ρ‹ΠΌ Π² println!(), Ρ‡Ρ‚ΠΎ ΠΈ ΠΎΡ‚Ρ€Π°ΠΆΠ΅Π½ΠΎ Π² Π²Ρ‹Π²Π΅Π΄Π΅Π½Π½ΠΎΠΉ сигнатурС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Index::index, которая Π² качСствС Π²Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Π΄ΠΆΠ΅Π½Π΅Ρ€ΠΈΠΊΠ° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ lifetime β€˜b. НиТС ΠΌΡ‹ пытаСмся Π·Π°ΠΈΠΌΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ data с мСньшим lifetime, Π½Π° Ρ‡Ρ‚ΠΎ ΠΈ ругаСтся компилятор. Если просто ΡƒΠ±Ρ€Π°Ρ‚ΡŒ println!(β€œ{}”, x), всС Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ висящий ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ/ссылка – Π½Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° – Ρ€Π°Π·Ρ‹ΠΌΠ΅Π½ΠΎΠ²Ρ‹Π²Π°Π½ΠΈΠ΅ Ρ‚Π°ΠΊΠΎΠΉ ссылки. На самом Π΄Π΅Π»Π΅ это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΠΉ, Ссли ΠΌΡ‹ пишСм свой дСструктор, Π½ΠΎ ΠΎΠ± этом ΠΏΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ Π² Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅.

Π—Π°ΠΌΠ°Π»Ρ‡ΠΈΠ²Π°Π½ΠΈΠ΅ Lifetime (Elision)

Π”ΠΎ появлСния вСрсии Rust 1.0 сигнатуры Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ со ссылками ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΠ»ΠΎΡΡŒ явно Π°Π½Π½ΠΎΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ lifetime. ПозднСС стало понятно, Ρ‡Ρ‚ΠΎ компилятор сам ΠΌΠΎΠΆΠ΅Ρ‚ Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΌ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ ΠΈ вывСсти всС Π·Π° нас, Ρ‡Ρ‚ΠΎ сдСлаСт ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΊΠΎΡ€ΠΎΡ‡Π΅ ΠΈ Π±ΠΎΠ»Π΅Π΅ Ρ‡ΠΈΡ‚Π°Π΅ΠΌΡ‹ΠΌΠΈ.

Π­Ρ‚Π° Ρ„ΠΈΡ‡Π° ΠΈ называСтся Π·Π°ΠΌΠ°Π»Ρ‡ΠΈΠ²Π°Π½ΠΈΠ΅ΠΌ lifetime ΠΈΠ»ΠΈ Elision. Π­Ρ‚ΠΎ плюс, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²ΠΎΡ‚ ΠΏΡ€Π°Π²ΠΈΠ»Π° вывСдСния lifetime ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π² сингратуру Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ достаточно ТСсткиС – ΠΈΠΌΠ΅Π΅Ρ‚ смысл Π·Π½Π°Ρ‚ΡŒ ΠΈΡ… Π½Π°ΠΈΠ·ΡƒΡΡ‚ΡŒ. А Π΅Ρ‰Ρ‘ ΠΎΠ½ΠΈ Π½Π΅ описаны Π² Rust Book явным ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.

Π˜ΡΠΏΡ€Π°Π²ΠΈΠΌ это досадноС Π½Π΅Π΄ΠΎΡ€Π°Π·ΡƒΠΌΠ΅Π½ΠΈΠ΅.

Lifetime ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ Π² сигнатуры трСмя способами:

  • &'a T – ссылка Π½Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Ρ‚ΠΈΠΏΠ° T.
  • &'a mut T – ΠΌΡƒΡ‚Π°Π±Π΅Π»ΡŒΠ½Π°Ρ ссылка Π½Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ T.
  • T<'a> – сигнатура Ρ‚ΠΈΠΏΠ° T Π² случаС, Ссли поля структур ΠΈΠ»ΠΈ сигнатуры ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² Ρ‚Ρ€Π΅ΠΉΡ‚ΠΎΠ² содСрТат ссылки.

Π’ΠΎ Π΅ΡΡ‚ΡŒ Ρƒ нас Π΅ΡΡ‚ΡŒ Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Π΅ lifetime, Ρ‡Ρ‚ΠΎ Π±Ρ‹Π»ΠΎ Π²ΠΈΠ΄Π½ΠΎ ΠΈ Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅. ΠŸΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΠΌ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΎΠ± ΠΈΡ… взаимосвязи. ΠžΠ±Ρ€Π°Ρ‰Π°ΡŽ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ Ссли Π²Π°ΠΌ Π½Π΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ Π²Ρ‹Π²Π΅Π΄Π΅Π½ΠΈΠ΅ Π·Π°ΠΌΠ°Π»Ρ‡ΠΈΠ²Π°Π΅ΠΌΡ‹Ρ… (elided) lifetime, Π²Ρ‹ всСгда ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΈΡ… явно.

ΠŸΡ€Π°Π²ΠΈΠ»Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ (ΠΈΡ… Π½Π°Π΄ΠΎ Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ):

  • ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Π·Π°ΠΌΠ°Π»Ρ‡ΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ (elided) lifetime Π² сигнатурС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΡƒΠ½ΠΈΠΊΠ°Π»Π΅Π½, Ρ‚.Π΅. Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fn do_something(a: &str, b: &str) Ρƒ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² a ΠΈ b Π±ΡƒΠ΄ΡƒΡ‚ Ρ€Π°Π·Π½Ρ‹Π΅ lifetime.
  • Если Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ссылочный Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ с Π·Π°ΠΌΠ°Π»Ρ‡ΠΈΠ²Π°Π΅ΠΌΡ‹ΠΌ ΠΈΠ»ΠΈ явным lifetime, Ρ‚ΠΎ всС Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Π΅ lifetime Π±ΡƒΠ΄ΡƒΡ‚ Π΅ΠΌΡƒ Ρ€Π°Π²Π½Ρ‹, Ρ‚.Π΅. fn do_something(s: &’a str) -> (&’a str, &’a str) Π² нашСм случаС Π²Π΅Ρ€Π½Π΅Ρ‚ ΠΊΠΎΡ€Ρ‚Π΅ΠΆ с двумя ссылками, Π½ΠΎ это ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈ структура с Π±ΠΎΠ»Π΅Π΅ Ρ‡Π΅ΠΌ ΠΎΠ΄Π½ΠΈΠΌ ссылочным ΠΏΠΎΠ»Π΅ΠΌ
  • Если ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ &self ΠΈΠ»ΠΈ &mut self, Ρ‚ΠΎ всС Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π·Π°ΠΌΠ°Π»Ρ‡ΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ lifetime Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π²Π΅Π΄Π΅Π½Ρ‹ Ρ€Π°Π²Π½Ρ‹ΠΌΠΈ lifetime ссылки Π½Π° self.
  • Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС Rust Π½Π΅ смоТСт вывСсти lifetime ΠΈ заставит вас ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ это явным ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ

Π”Π°Π²Π°ΠΉΡ‚Π΅ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ посмотрим Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ…:

        fn print(s: &str);                                      // ΠΌΠΎΠ»Ρ‡Π° Π΄Π°
fn print<'a>(s: &'a str);                               // явно
 
fn debug(lvl: usize, s: &str);                          // ΠΌΠΎΠ»Ρ‡Π°
fn debug<'a>(lvl: usize, s: &'a str);                   // явно
 
fn substr(s: &str, until: usize) -> &str;               // ΠΌΠΎΠ»Ρ‡Π°
fn substr<'a>(s: &'a str, until: usize) -> &'a str;     // явно
 
fn get_str() -> &str;                                   // Ρ‚Π°ΠΊ нСльзя
 
fn frob(s: &str, t: &str) -> &str;                      // Ρ‚Π°ΠΊ нСльзя
 
fn get_mut(&mut self) -> &mut T;                        // ΠΌΠΎΠ»Ρ‡Π°
fn get_mut<'a>(&'a mut self) -> &'a mut T;              // явно
 
fn args<T: ToCStr>(&mut self, args: &[T]) -> &mut Command                  // ΠΌΠΎΠ»Ρ‡Π°
fn args<'a, 'b, T: ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command // явно
 
fn new(buf: &mut [u8]) -> BufWriter;                    // ΠΌΠΎΠ»Ρ‡Π°
fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a>          // явно
    

Π’Ρ‹Π²ΠΎΠ΄

Начав Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ эту ΡΡ‚Π°Ρ‚ΡŒΡŽ, Π²Ρ‹ Ρ…ΠΎΡ‚Π΅Π»ΠΈ ΠΈΠ·Π±Π°Π²ΠΈΡ‚ΡŒΡΡ ΠΎΡ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ. На Π΄Π΅Π»Π΅ всС ΠΏΡ€ΠΎΠ·Π°ΠΈΡ‡Π½ΠΎ: Π½Π°Π΄ΠΎ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΊΠ°ΠΊ Π² Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π²Π»Π°Π΄Π΅Π½ΠΈΠ΅ ΠΈ заимствованиС Π² Rust, Π° Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΎΡΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ Ρ€ΡƒΠ³Π°ΡŽΡ‰ΠΈΠΉΡΡ компилятор ΠΊΠ°ΠΊ Π²Π΅Π»ΠΈΠΊΠΎΠ΅ Π±Π»Π°Π³ΠΎ. Π”Π°, ΠΎΠ½ заставит вас ΠΏΠ΅Ρ€Π΅ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΊΠΎΠ΄, Π·Π°Ρ‚ΠΎ этот ΠΊΠΎΠ΄ Π½Π΅ выстрСлит Π²Π°ΠΌ Π² Π½ΠΎΠ³Ρƒ, Ρ€ΡƒΠΊΡƒ ΠΈΠ»ΠΈ Π² Π³ΠΎΠ»ΠΎΠ²Ρƒ 31 дСкабря Π² 23:30 ΠΈ Π½Π΅ заставит ΠΎΡ‚Π»Π°ΠΆΠΈΠ²Π°Ρ‚ΡŒ сСбя Π² самоС нСподходящСС врСмя. Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π°Π· ΠΌΡ‹ заглянСм Π΅Ρ‰Ρ‘ Π³Π»ΡƒΠ±ΠΆΠ΅ ΠΏΠΎΠ΄ ΠΊΠ°ΠΏΠΎΡ‚ ΠΈ Π½Π΅ΠΌΠ½ΠΎΠΆΠΊΠΎ ΠΏΡ€ΠΈΠΎΡ‚ΠΊΡ€ΠΎΠ΅ΠΌ Ρ‚Π°ΠΉΠ½Ρƒ, ΠΊΠ°ΠΊ компилятор Π΄Π΅Π»Π°Π΅Ρ‚ магию владСния. Π—Π° ΠΏΡ€Π΅Π΄Π΅Π»Π°ΠΌΠΈ этой ΡΡ‚Π°Ρ‚ΡŒΠΈ ΠΎΡΡ‚Π°Π»ΠΈΡΡŒ Ρ‚Π°ΠΊΠΈΠ΅ Π²Π°ΠΆΠ½Ρ‹Π΅ Ρ‚Π΅ΠΌΡ‹, ΠΊΠ°ΠΊ автоматичСскоС ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹ΠΌΠΈ Π² ΠΊΡƒΡ‡Π΅ ΠΈ связываниС ΠΈΡ… с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ Π½Π° стСкС.

Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ популярных языках Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΠΉΡ‚ΠΈ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста».

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊΠΈ

ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ

 
 

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•

Подпишись

Π½Π° push-увСдомлСния