Rust: алғашқы қадамнан жеке жоспарлау құралына дейін 21-сабақ (барлығы 35)
Өзгермелі қарызға алу
21-сабақ. Мәтінді функция арқылы өзгертіп, оған басқа қатынау қашан қайта рұқсат етілетінін түсіндіру.
Мәтін ИИ көмегімен аударылды.
Алдын ала: 19–20-сабақтар. &title иесін неге сақтайтыны түсініксіз болса, 20-сабаққа оралыңыз.
Таныс бейне және тірек сызба
Кітапханадағы анықтамалықты бірнеше адам бір мезгілде оқи алады. Біреу оның бетін түзетіп жатқанда, басқалар аяқталмаған түзетуді көрмеуі үшін оған уақытша жеке қатынау керек. Өзгермелі қарызға алу иелікті бермей, мәнді уақытша өзгертуге рұқсат етеді. Бейненің шегі бар: Rust кітапхана рұқсатын таратпайды, кодтағы сілтемелердің қолданылуын тексереді.
Иесі mut → &mut → функциядағы өзгеріс → сілтеменің соңғы қолданылуы → иесі қайта қатынайды. Мәтінді жауып, осы тізбекті өзіңіз қалпына келтіріңіз. Бұрынғы let mut мәнді өз атауы арқылы өзгертуге рұқсат береді. Жаңа &mut title өзгермелі сілтеме жасайды, ал параметрдегі &mut String оның түрін көрсетеді. &mut шақыруда да, параметр түрінде де жазылады; бұл мәтінді екі рет өзгерту емес.
Алғашқы мысал
organizer жобасында бұрынғы src/main.rs мазмұнын бөлек сақтап, файлды толық ауыстырыңыз. Cargo.toml бар бумада cargo run орындаңыз. Басқа файлдар мен тәуелділіктер өзгермейді. Нәтиженің бір жолын алдын ала болжаңыз; нәтиже блогында Cargo хабарлары жоқ.
18-сабақтағы push_str әдісі String соңына мәтін қосады. Төмендегі функция осы өзгеріске уақытша рұқсат алады; одан кейін иесі main ішінде қалады.
fn mark_done(title: &mut String) {
title.push_str(" — дайын");
}
fn main() {
let mut title = String::from("Оқу");
mark_done(&mut title);
println!("Тапсырма: {title}");
}
Тапсырма: Оқу — дайын
mark_done мәтінге иелік етпейді және оны қайтармайды: сілтеме бастапқы мәнді өзгертуге мүмкіндік береді. Иесіндегі mut пен сілтемедегі &mut әртүрлі міндет атқарады. mut бар екен деп кез келген сілтеме өзгермелі бола салмайды.
Өзгертуге бір ғана қатынау
Өзгермелі сілтеме әлі қолданылатын кезде сол мәнге оқу сілтемесін қатар қолдануға болмайды. Әйтпесе оқырман өзгеріп жатқан мәтінді көруі мүмкін. Келесі бөлек мысал әдейі құрастырылмайды; E0502 бір-біріне қайшы қарызға алуды көрсетеді:
fn main() {
let mut title = String::from("Жоспар");
let reader = &title;
let writer = &mut title;
writer.push_str("!");
println!("{reader}");
}
Мұнда reader атауы writer жасалғаннан кейін де керек, сондықтан екі қатынаудың мерзімі қабаттасады. Түзету үшін оқуды өзгермелі қарызға алудан бұрын аяқтаңыз. Ойланбай clone() қоспаңыз: ол бастапқы мәтінді өзгертудің орнына басқа көшірме жасар еді.
fn main() {
let mut title = String::from("Жоспар");
let reader = &title;
println!("Дейін: {reader}");
let writer = &mut title;
writer.push_str("!");
println!("Кейін: {title}");
}
Дейін: Жоспар
Кейін: Жоспар!
Компилятор reader соңғы рет writer жасалғанға дейін қолданылғанын көреді; екі атау бір блокта қала алады. Сол сияқты writer соңғы рет қолданылғаннан кейін иесі мәнге қайта қатынайды. Бір мәнге қатар қолданылатын екі өзгермелі сілтеме де жарамайды. Бұл ереже бағдарламаның бүкіл бойында мәтінді тек бір рет өзгерту керек дегенді білдірмейді; қабаттасқан қолданыстарға қатысты.
Түсінгеніңізді тексеріңіз
let mut titleмен&mut titleнеге екеуі де керек?readerбар қате мысал неге құрастырылмайды?- Қай әрекеттен кейін иесі
titleмәнін қайта оқи алады?
Тексеру: иесі өзгертуге рұқсат береді, сілтеме бұл құқықты уақытша өткізеді; reader оқуы жазумен қабаттасады; өзгермелі сілтеменің соңғы қолданылуынан кейін. Тірек сызбаны қарап алмай қайталаңыз.
Тапсырма
Міндетті. add_label(title: &mut String, label: &str) функциясын жазыңыз: ол label мәтінін жолдың соңына қоссын. &str түрі 9-сабақтан таныс: мәтінге иелік етпей қатынау; "!" литералын &str ретінде беруге болады. Жоспар мәтінімен өзгермелі String жасап, функцияны "!" мәнімен екі рет шақырыңыз. Нәтиже Жоспар!! болсын. Алдымен болжаңыз, кейін іске қосыңыз. clone() қолданбаңыз және функциядан String қайтармаңыз.
Шекара. Параметрдегі &mut String орнына &String жазып, компилятордың неге бас тартатынын түсіндіріңіз. Содан кейін жұмыс істейтін жазылымды қайтарыңыз.
Көмек
Иесіне let mut, ал шақыруларға add_label(&mut title, "!") керек. Функция ішінде title.push_str(label) жазыңыз. Бірінші шақырудың қарызға алуы екіншісі басталғанға дейін аяқталады.
Өз бетіңізше орындағаннан кейінгі үлгі жауап
fn add_label(title: &mut String, label: &str) {
title.push_str(label);
}
fn main() {
let mut title = String::from("Жоспар");
add_label(&mut title, "!");
add_label(&mut title, "!");
println!("{title}");
}
Жоспар!!
Екі шақыру бір мәтінді өзгертеді; оның иесі main ішінде қалады. Өзгермелі сілтемелер туралы ресми түсіндірме.
Пікірлер (0)
Пікір қалдыру үшін кіріңіз →
Әзірге пікір жоқ. Бірінші болыңыз.