Հասկանալով փոխառությունը ժանգով
Փոխառությունը բարդ թեմա է՝ կապված սեփականության հետ։ Դա հասկանալը կարևոր է Rust-ում հիշողության կառավարման հետ աշխատելու համար:
Rust-ը օգտագործում է փոխառության ստուգիչ՝ իր սեփականության կանոնները պահպանելու և ծրագրերի հիշողության անվտանգությունն ապահովելու համար: Սեփականության կանոնները թելադրում են, թե ինչպես է Rust-ը կառավարում հիշողությունը կույտի և կույտի վրա:
Rust ծրագրեր գրելիս պետք է օգտագործեք փոփոխականներ՝ չփոխելով համապատասխան արժեքի սեփականությունը: Rust-ն ապահովում է փոխառության կայուն մեխանիզմ՝ խրախուսելու ճկունությունը և կոդի վերօգտագործումը:
Ի՞նչ է ժանգով փոխառությունը:
Փոխառությունը փոփոխականի արժեքին մուտք գործելն է՝ առանց փոփոխականին սեփականության իրավունք վերցնելու՝ սեփականատիրոջը հղում անելով: Փոխառության ստուգիչն ապահովում է, որ հղումը վավեր է, և տվյալները չեն հեռացվում՝ օգտագործելով կյանքի ժամկետներ կոչվող կառուցվածքը:
Կյանքի ժամկետն այն է, թե որքան երկար է գոյություն ունի փոփոխականը: Կյանքի տևողությունը սկսվում է փոփոխականների ստեղծմամբ և ավարտվում փոփոխական ոչնչացմամբ: Դուք կարող եք փոխառել փոփոխականի սեփականությունը, և երբ փոխառված հղումը դուրս է գալիս շրջանակից, սեփականության իրավունքը վերադառնում է սեփականատեր փոփոխականին: Փոխառությունը մի փոքր նման է այն ցուցիչներին, որոնք դուք կգտնեք այնպիսի լեզուներում, ինչպիսիք են C++-ը և Go-ն: Բայց Rust կոմպիլյատորն օգտագործում է փոխառության ստուգիչը՝ ապահովելու ծրագրերի հիշողության անվտանգությունը:
Ժանգով փոխառության օրինակ
Դուք կարող եք փոխառել փոփոխականի սեփականությունը՝ հղում կատարելով սեփականատիրոջը՝ օգտագործելով նշան (&) նշանը:
fn main() {
let x = String::from("hello"); // x owns "hello"
let y = &x; // y references x, borrows "hello"
println!("{}", x);
println!("{}", y)
}
Առանց հղում անելով պարտք վերցնելու՝ ծրագիրը խուճապի կմատնվեր։ Դա կխախտի սեփականության կանոնը, ըստ որի արժեքը կարող է ունենալ մեկ սեփականատեր, և երկու փոփոխականները չեն կարող մատնանշել նույն հիշողության վայրը: Փոխառությունը կարող է շատ օգտակար լինել գործառույթների մեջ: Ահա ֆունկցիայի մեջ փոխառելու օրինակ՝ սեփականության իրավունքը պահպանելու համար՝ միաժամանակ կանչելով այլ գործառույթներ, որոնք որպես արգումենտ ընդունում են տեղական փոփոխականները:
fn print_even(vectr: &Vec<i32>) {
for values in vectr {
if values % 2 == 0 {
println!("{}", values);
}
}
}
print_even ֆունկցիան որպես արգումենտ հղում է անում 32-բիթանոց ամբողջ թվերի վեկտորին: Այնուհետև այն տպում է արժեքների տողեր, որոնք վեկտորում երկուսի բազմապատիկ են՝ օգտագործելով for-loop և println! մակրո.
fn main() {
let number_vector = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
print_even(&number_vector); // ownership is borrowed, not moved
println!("The main function retains ownership of the number vector{:?}", number_vector)
}
Հիմնական ֆունկցիան հայտարարում է number_vector փոփոխականը և դրան վերագրում է 32-բիթանոց ամբողջ թվերի վեկտոր։ Այնուհետև այն կանչում է print_even ֆունկցիան և այն հղում է փոխանցում number_vector փոփոխականին՝ օգտագործելով ամպերսանդի նշանը:
Հիմնական ֆունկցիան պահպանում է number_vector փոփոխականի սեփականությունը, այն կարող է շարունակել օգտագործել արժեքը իր հիշողության վայրում:
Փոխառություն և փոփոխվող հղումներ
Գործառույթները կարող են նաև փոփոխել փոխառված փոփոխականները՝ օգտագործելով դրանց փոփոխվող հղումները՝ նախքան սեփականության իրավունքը վերադարձնելը:
Այնուամենայնիվ, ի տարբերություն սովորական փոփոխականների, որոնք կարող են mutable-ի սահմանվել՝ օգտագործելով mut բանալի բառը, դուք պետք է փոփոխական հղումները նախածանցի դրեք ամպերսանդի նշանով:
Նախքան փոփոխական հղումներ կատարելը, փոփոխականը, որը ցանկանում եք փոփոխել, պետք է փոփոխական լինի:
fn remove_value(vectr: &mut Vec<i32>) -> &Vec<i32> {
vectr.remove(4);
return vectr
}
remove_value ֆունկցիան ընդունում է 32-բիթանոց ամբողջ թվերի փոփոխվող վեկտորի հղումը: Այն վերադարձնում է 32-բիթանոց ամբողջ թվերի վեկտորը չորրորդ ինդեքսի վեկտորի արժեքը հեռացնելուց հետո:
fn main() {
let mut nums = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
remove_value(&mut nums); // mutable reference here
println!("{:?}", nums);
}
Ֆունկցիան փոփոխում է nums վեկտորը՝ կանչելով remove_value և որպես արգումենտ փոխանցելով վեկտորի փոփոխվող հղումը։ Վեկտորը տպելիս վեկտորի նախորդ չորրորդ ինդեքսը գոյություն չունի:
Ուշադրություն դարձրեք, որ արգումենտը հղում է փոփոխական վեկտորին:
Կարևոր է հասկանալ սեփականության իրավունքը և փոխառությունը
Դուք պետք է հասկանաք սեփականության իրավունքը և փոխառությունը, որպեսզի գրեք արդյունավետ, հիշողության համար անվտանգ Rust կոդը, որը հավաքվում և գործարկվում է: Եթե ձեր կոդը չի հետևում սեփականության կանոններին, ապա պարտքի ստուգիչը կհայտնաբերի այն: Դուք պետք է ձեր ծրագիրը ապահով դարձնեք հիշողության մեջ, որպեսզի Rust-ը այն կազմի:
Փոխառության ստուգիչը նյարդայնացնում է, երբ դուք նոր եք Rust-ում: Բայց քանի որ ավելի շատ Rust կոդ եք գրում, դուք կվարժվեք դրան և փորձ ձեռք կբերեք հիշողության համար անվտանգ Rust կոդ գրելու հարցում: