Rust: алғашқы қадамнан жеке жоспарлау құралына дейін 19-сабақ (барлығы 20)
Иелік және мәнді беру
Сабақ 19. String мәні берілгеннен кейін ескі атау неге қолжетімсіз екенін түсіндіру.
Мәтін ИИ көмегімен аударылды.
Алдын ала: 1–18-сабақтар. Атауды қай жерде қолдануға болатыны түсініксіз болса, жад пен қолданылу аясын қайталаңыз.
Ереже және тұрмыстық бейне
String мәнінің иесі бар: мәтіннің басқарылатын дерегіне жауап беретін бағдарлама бөлігі. Осы мән басқа атауға берілгенде, иелік ауысады (move). Мұны қоймадағы затқа берілген жалғыз талонға ұқсатыңыз: талонды берген адам енді затты ала алмайды. Бейненің шегі: Rust мәтін байттарын міндетті түрде басқа нақты мекенжайға апармайды. Ауысу қай атаудың мәнді қолдана алатынын білдіреді.
Тірек карта: жасау → иелену → беру → ескі атау жабылады → жаңа иесі ресурсты кейін босатады. Кодқа қарамай осы жолды айтып көріңіз.
Иеліктің ауысуын көріңіз
6-сабақтағы organizer жобасында бұрынғы src/main.rs файлын бөлек сақтаңыз. Файлды келесі кодпен толық ауыстырып, Cargo.toml бар бумада cargo run орындаңыз. Тәуелділік қосылмайды. Нәтиже блогында тек бағдарламаның мәтіні берілген.
fn print_title(title: String) {
println!("Тапсырма: {title}");
}
fn main() {
let title = String::from("Оқу");
print_title(title);
}
Тапсырма: Оқу
title: String параметрі шақыру кезінде иелікті алады. Функция мәнді қолдана алады. Функция аяқталғанда, оның иелігіндегі мәтін ресурсы автоматты түрде босайды. main ішіндегі бұрынғы title атауын одан кейін қолдануға болмайды. Мына талпыныс E0382 қатесімен тоқтайды:
fn print_title(title: String) {
println!("{title}");
}
fn main() {
let title = String::from("Оқу");
print_title(title);
println!("{title}");
}
Компилятор мәтін босап қалды деп тұрған жоқ. Ол мәні басқаға берілген, ал ресурсы босатылып кетуі мүмкін ескі атауды қолдануға жол бермейді. Мысалды өзіңіз тексермей тұрып, қай жолға шағым түсетінін болжаңыз.
Сандар неге басқаша?
u32 түрінде Copy трейті бар. Трейт — түрдің қасиетін не ортақ әрекетін сипаттайтын ереже; өз трейтімізді 46-сабақта жазамыз. Copy бар мән берілгенде, оның бөлек сандық көшірмесі жасалады, сондықтан бұрынғы атау жарамды қалады. Келесі кодта жаңа жазылым жоқ:
fn print_minutes(minutes: u32) {
println!("Функцияда: {minutes}");
}
fn main() {
let minutes = 15;
print_minutes(minutes);
println!("Сыртта: {minutes}");
}
Функцияда: 15
Сыртта: 15
Элементтері Copy болатын жиым да Copy болуы мүмкін. Бұл әр жинақ немесе мәтін өздігінен көшіріледі деген сөз емес. Сандық мысал ережесін барлық түрге таратпаңыз.
Егер мәтінге шынымен екі тәуелсіз иесі керек болса, clone() мәтін дерегінің жаңа көшірмесі бар екінші String жасайды. Нүкте 15-сабақтағыдай әдісті шақырады; clone — «тәуелсіз көшірме жаса». Бұл жад кеңістігін қажет етуі мүмкін, сондықтан саналы түрде қолданыңыз:
fn main() {
let first = String::from("Оқу");
let second = first.clone();
println!("Біріншісі: {first}");
println!("Екіншісі: {second}");
}
Біріншісі: Оқу
Екіншісі: Оқу
Екі иесі керек кезде көшіру орынды. Функция тек мәтінді оқыса, келесі сабақта оны көшірмей сілтеме арқылы береміз.
Еске түсіру
let b = a; кейін a түрі String болса, қай атау жарамды? u32 болса ше? Жауап: String үшін тек b; u32 үшін бөлек сандық мәндері бар екі атау да. Мұны қойма талонының бейнесімен және оның шегімен түсіндіріңіз.
Тапсырма
Тапсырмаға дейін таныс mut таңбасының тағы бір орнын қараңыз: fn decorate(mut title: String) ішінде ол функция параметрінің атауына қатысты. Функция мәнге иелік етіп, оған мәтін қоса алады. Бірақ бұл main ішіндегі ескі атауды мән берілгеннен кейін қайта жарамды етпейді.
Міндетті. decorate(mut title: String) -> String жазыңыз. Ол push_str арқылы ! қосып, мәтінді қайтарады. main ішінде String::from("Жоспар") мәнін беріп, қайтқан мәнді сақтап, Жоспар! шығарыңыз. Шақыруға дейін, функция ішінде, қайтқаннан кейін иесі қайда екенін айтыңыз. clone() қолданбаңыз: бір мәнді беріп, қайта алу жеткілікті.
Ишара
Параметрді mut title: String деп жазыңыз: 9-сабақтағы mut енді функцияның өз параметр атауы арқылы мәнді өзгертуіне рұқсат береді. Соңғы өрнек title болсын, артында ; болмасын. Қайтқан мәнді main ішінде жаңа атауға беріңіз.
Өз талпынысыңыздан кейінгі үлгі
fn decorate(mut title: String) -> String {
title.push_str("!");
title
}
fn main() {
let original = String::from("Жоспар");
let decorated = decorate(original);
println!("{decorated}");
}
Жоспар!
Иелік original атауынан параметрге, кейін decorated атауына өтеді. Rust иелігі туралы ресми тарау.
Пікірлер (0)
Пікір қалдыру үшін кіріңіз →
Әзірге пікір жоқ. Бірінші болыңыз.