聊聊Rust中的“借用”
在Rust的世界里,想要優(yōu)雅地共享數(shù)據(jù),就得聊聊“借用”這檔子事。想象一下,朋友有個(gè)寶貝,咱們不奪人所愛,只是暫時(shí)借用一下,用完還得物歸原主,這就是借用(Borrowing)的核心思想。
借用基礎(chǔ)操作
來看看這行代碼:
let y = &x;
這里,y就是一個(gè)指向x的引用,就像你跟朋友說:“嘿,借你那5塊錢瞅瞅?!币榭磞指向的值,得用解引用運(yùn)算符,就像這樣:
assert_eq!(5, *y);
就像借來的錢終究要還,引用離開作用域后,它指向的數(shù)據(jù)依然安好無恙。
函數(shù)中的借用
比如,我們要計(jì)算字符串s1的長(zhǎng)度,但又不想轉(zhuǎn)讓所有權(quán),怎么辦?用引用傳參唄!
fn calculate_length(s: &String) -> usize {
s.len()
}
在main函數(shù)里,我們這么用:
let s1 = String::from("hello");
let len = calculate_length(&s1);
println!("The length of '{}' is {}.", s1, len);
瞧見沒,s1的引用被傳遞給了calculate_length函數(shù),既測(cè)了長(zhǎng)度,又沒動(dòng)人家的奶酪,多和諧!
可變引用:想要改一改?
不過,要是想修改借用的東西,就像你不僅想牽牽手還想給妹子一個(gè)擁抱,那就得用可變引用了,得這么寫:
fn change(some_string: &mut String) {
some_string.push_str(", world");
}
記得,被借用的變量也得是可變的,就像這樣初始化:
let mut s = String::from("hello");
change(&mut s);
這下,你的“hello”就能變成“hello, world”了。
可變引用的限制
但別太貪心,Rust規(guī)定,在同一時(shí)間,對(duì)于同一個(gè)數(shù)據(jù),只能有一個(gè)可變引用存在。比如這段代碼就會(huì)報(bào)錯(cuò):
let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s; // 這里會(huì)報(bào)錯(cuò)
為啥?因?yàn)镽ust的borrow checker(借用檢查器)在盯著呢,它絕不允許數(shù)據(jù)競(jìng)爭(zhēng)這種危險(xiǎn)的事情發(fā)生,那可是軟件bug的大戶。
大括號(hào):作用域的藝術(shù)
遇到借用沖突,別急,大括號(hào)是你的解藥。它能幫你控制變量的作用域,這樣就能巧妙避開借用檢查器的紅線:
{
let r1 = &mut s;
} // r1的生命到此為止
let r2 = &mut s; // 現(xiàn)在可以再創(chuàng)建一個(gè)可變引用了
總結(jié)一下
- 借用讓代碼更簡(jiǎn)潔,還能避免所有權(quán)的頻繁轉(zhuǎn)移。
- 要修改數(shù)據(jù),記得用可變引用&mut。
- 同一時(shí)間,一個(gè)數(shù)據(jù)只能被一個(gè)可變引用借用,但可以有任意數(shù)量的不可變引用。
- 利用大括號(hào)控制作用域,能解決很多借用問題。
怎么樣,是不是覺得Rust的借用機(jī)制既嚴(yán)格又貼心?這都是為了咱們程序的安全和穩(wěn)定?。?/p>