今天我們來(lái)學(xué)習(xí)一下Rust中的引用與借用侠讯。我在看官方教程講解引用與借用的時(shí)候挖藏,很困惑,分不清引用與借用继低。在第二遍理解的時(shí)候熬苍,大概能夠理清了。
先來(lái)解釋一下 引用
袁翁,Rust官方文檔中的解釋是 允許使用值但不獲取其所有權(quán)
柴底。與其他語(yǔ)言基本一樣,可以理解為就是一個(gè)數(shù)據(jù)指針粱胜。
再來(lái)說(shuō)一下 借用
柄驻,官方文檔中解釋借用是指 將獲取引用作為函數(shù)參數(shù)稱(chēng)為 借用(borrowing)
。我的理解是焙压,借用
不是一個(gè)具體的東西鸿脓,而是一種行為,對(duì)于Rust來(lái)說(shuō)涯曲,當(dāng)我們定義一下函數(shù)野哭,而函數(shù)的形參是一個(gè)引用,或者說(shuō)是一個(gè)指針時(shí)幻件,這種行為拨黔,就叫做借用〈铝ぃ可能不太精確地解釋?zhuān)梢岳斫鉃槔橛?dāng)我們調(diào)用這個(gè)函數(shù)時(shí)贺待,這個(gè)函數(shù)借用了外面某個(gè)數(shù)據(jù)的訪問(wèn)權(quán)限,但是并不擁有外面數(shù)據(jù)的所有權(quán)零截。就像生活中你借了某人的一個(gè)網(wǎng)站賬號(hào)麸塞,這時(shí),你可以訪問(wèn)網(wǎng)站上的內(nèi)容了涧衙,但是你沒(méi)有這個(gè)賬號(hào)的所有權(quán)哪工。
當(dāng)將引用作為參數(shù)時(shí),也分為
可變引用
和不可變引用
不可變引用
fn main() {
let mut str = String::from("Hello");
borrowing(&str);
}
fn borrowing(str: &String) {
println!("Borrowing Str: {}", str);
}
可變引用
fn main() {
let mut str = String::from("Hello");
println!("Source Str: {}", str); // 這里打印出原來(lái)的字符串
mut_borrowing(&mut str); // 調(diào)用后绍撞,字符串被改變
println!("Str: {}", str); // 打印改變后的字符串
}
fn mut_borrowing(str: &mut String) {
str.push_str(" , Rust");
}
有一條很重要的規(guī)則要記住正勒,在同一作用域中,一個(gè)數(shù)據(jù)傻铣,有且只有一個(gè)
可變
引用章贞。
下面一段代碼就是錯(cuò)的,編譯不過(guò)非洲,因?yàn)橥蛔饔糜蛳卵枷蓿粋€(gè)數(shù)據(jù)有多個(gè)可變引用
fn main() {
let mut str = String::from("Hello");
let r1 = &mut str;
let r2 = &mut str;
println!("{}, {}", r1, r2);
}
關(guān)于數(shù)據(jù)競(jìng)爭(zhēng)
Rust 這樣的限制可以避免數(shù)據(jù)競(jìng)爭(zhēng)
,數(shù)據(jù)競(jìng)爭(zhēng)可能由下面三個(gè)原因引起
- 兩個(gè)或更多指針同時(shí)訪問(wèn)同一數(shù)據(jù)两踏。
- 至少有一個(gè)指針被用來(lái)寫(xiě)入數(shù)據(jù)败京。
- 沒(méi)有同步數(shù)據(jù)訪問(wèn)的機(jī)制。
懸垂引用(Dangling References)
在擁有指針的編程語(yǔ)言中很容易出現(xiàn)一種情況梦染,一個(gè)指針還存在赡麦,但是指針指向的內(nèi)存已經(jīng)被釋放。在Rust中帕识,這種為懸垂引用
泛粹。在Rust中,Rust編譯器確保指針永遠(yuǎn)不會(huì)變?yōu)閼掖範(fàn)顟B(tài)肮疗。
看下面的代碼晶姊,編譯會(huì)出錯(cuò)
fn main() {
let s = dangling();
}
// 這個(gè)函數(shù)返回了字符串的引用,但是當(dāng)這個(gè)函數(shù)結(jié)束時(shí)伪货,字符串內(nèi)存會(huì)被釋放们衙,&s變?yōu)閼掖範(fàn)顟B(tài),所以編譯出錯(cuò)
fn dangling() -> &String {
let s = String::from("Hello rust");
&s
}
引用的規(guī)則
- 在任意給定時(shí)間碱呼,要么 只能有一個(gè)可變引用蒙挑,要么 只能有多個(gè)不可變引用。
- 引用必須總是有效愚臀。