Modül dersleri (2/2)
Referanslar ve Ödünç Alma
Rust'ta sahipliği işlevlere aktarmak sıkıcı olabilir. Rust bunu çözmek için referanslar (&) kullanır.
Bir değere referans oluşturmaya Ödünç Alma denir.
Değişmez Referanslar
Bir başvuru, türe veya değişkene & sembolü getirilerek bildirilir. Varsayılan olarak referanslar değişmez: değerin okunmasına izin veriyorlar ancak değiştirilmiyorlar.
fn main() {
let s1 = String::from("hello");
// We pass a reference to s1, not ownership
let len = calculate_length(&s1);
// s1 is still usable here!
println!("The length of '{}' is {}.", s1, len);
}
fn calculate_length(s: &String) -> usize { // s is a reference to a String
s.len()
} // Here, s goes out of scope, but since it doesn't own the value, nothing happensDeğişken Referanslar
Ödünç alınan bir değeri değiştirmeniz gerekiyorsa, &mut ile değişebilir bir referans kullanmanız gerekir. Orijinal değişkenin ayrıca mut ile değişken olarak bildirilmesi gerekir:
fn main() {
let mut s = String::from("hello");
// We pass a mutable reference
change(&mut s);
println!("{}", s); // Prints "hello, world"
}
fn change(some_string: &mut String) {
some_string.push_str(", world");
}Borçlanma Kuralları
Derleme sırasında bellek bozulmasını ve veri yarışlarını önlemek için Rust iki temel kuralı uygular:
- Bir değere aynı anda istediğiniz sayıda değişmez referansa (
&T) sahip olabilirsiniz. - VEYA aynı anda bir değere yönelik tam olarak tek bir değiştirilebilir referansa (
&mut T) sahip olabilirsiniz.
Aynı kapsamda, aynı değer için değişmez ve değiştirilebilir referansları kesinlikle karıştıramazsınız:
let mut s = String::from("hello");
let r1 = &s; // Valid
let r2 = &s; // Valid
// let r3 = &mut s; // COMPILATION ERROR! You cannot create &mut s if s is already borrowed as immutableReferans Kapsamı ve Sözcük Dışı Yaşam Süreleri (NLL)
Tarihsel olarak bir referansın kapsamı, oluşturulduğu bloğun sonuna kadar devam ediyordu. Bugün, Rust'un derleyicisi Sözcük Dışı Yaşam Süreleri (NLL) sayesinde daha akıllıdır: bir referansın kapsamı, bloğun sonunda olması gerekmeden, gerçekte kullanıldığı son satırda biter.
Bu, aşağıdaki kodu tamamen geçerli kılar:
let mut s = String::from("hello");
let r1 = &s;
let r2 = &s;
println!("{} and {}", r1, r2); // Last use of r1 and r2. The immutable references expire here!
let r3 = &mut s; // Valid! No active immutable references exist at this pointKendin dene
& sembolünü kullanarak, hesaplama_uzunluğu işlevine s1'in değişmez bir referansını iletin.
İpucu göster
Dizeye değişmez bir başvuru iletmek için `/* TODO \_/`'yu`&s1` ile değiştirin.
3 denemeden sonra çözüm mevcut
s değişkenini değişken yapın (let mut s) ve dizeyi değiştirmesine izin vermek için change işlevine değiştirilebilir bir referans (&mut s) iletin.
İpucu göster
'Let s' yerine 'let mut s' kullanın ve 'change(&mut s);' komutunu çağırın.
3 denemeden sonra çözüm mevcut
Declare a variable s containing String::from("Rust"). Create two distinct immutable references r1 and r2 to s, and finally print both references separated by a space using the println! macro.
İpucu göster
Assign `let r1 = &s;` and `let r2 = &s;` to obtain two immutable references, then print them with `println!("{} {}", r1, r2);`.
3 denemeden sonra çözüm mevcut