變量,基本類型,函數(shù),注釋和控制流,這些幾乎是每種編程語(yǔ)言都具有的編程概念。
這些基礎(chǔ)概念將存在于每個(gè) Rust 程序中,及早學(xué)習(xí)它們將使你以最快的速度學(xué)習(xí) Rust 的使用。
首先必須說(shuō)明,Rust 是強(qiáng)類型語(yǔ)言,但具有自動(dòng)判斷變量類型的能力。這很容易讓人與弱類型語(yǔ)言產(chǎn)生混淆。
如果要聲明變量,需要使用 let 關(guān)鍵字。例如:
let a = 123;
只學(xué)習(xí)過(guò) JavaScript 的開(kāi)發(fā)者對(duì)這句話很敏感,只學(xué)習(xí)過(guò) C 語(yǔ)言的開(kāi)發(fā)者對(duì)這句話很不理解。
在這句聲明語(yǔ)句之后,以下三行代碼都是被禁止的:
a = "abc"; a = 4.56; a = 456;
第一行的錯(cuò)誤在于當(dāng)聲明 a 是 123 以后,a 就被確定為整型數(shù)字,不能把字符串類型的值賦給它。
第二行的錯(cuò)誤在于自動(dòng)轉(zhuǎn)換數(shù)字精度有損失,Rust 語(yǔ)言不允許精度有損失的自動(dòng)數(shù)據(jù)類型轉(zhuǎn)換。
第三行的錯(cuò)誤在于 a 不是個(gè)可變變量。
前兩種錯(cuò)誤很容易理解,但第三個(gè)是什么意思?難道 a 不是個(gè)變量嗎?
這就牽扯到了 Rust 語(yǔ)言為了高并發(fā)安全而做的設(shè)計(jì):在語(yǔ)言層面盡量少的讓變量的值可以改變。所以 a 的值不可變。但這不意味著 a 不是"變量"(英文中的 variable),官方文檔稱 a 這種變量為"不可變變量"。
如果我們編寫(xiě)的程序的一部分在假設(shè)值永遠(yuǎn)不會(huì)改變的情況下運(yùn)行,而我們代碼的另一部分在改變?cè)撝?,那么代碼的第一部分可能就不會(huì)按照設(shè)計(jì)的意圖去運(yùn)轉(zhuǎn)。由于這種原因造成的錯(cuò)誤很難在事后找到。這是 Rust 語(yǔ)言設(shè)計(jì)這種機(jī)制的原因。
當(dāng)然,使變量變得"可變"(mutable)只需一個(gè) mut 關(guān)鍵字。
let mut a = 123; a = 456;
這個(gè)程序是正確的。
既然不可變變量是不可變的,那不就是常量嗎?為什么叫變量?
變量和常量還是有區(qū)別的。在 Rust 中,以下程序是合法的:
let a = 123; let a = 456;
但是如果 a 是常量就不合法:
const a: i32 = 123; let a = 456;
變量的值可以"重新綁定",但在"重新綁定"以前不能私自被改變,這樣可以確保在每一次"綁定"之后的區(qū)域里編譯器可以充分的推理程序邏輯。 雖然 Rust 有自動(dòng)判斷類型的功能,但有些情況下聲明類型更加方便:
let a: u64 = 123;
這里聲明了 a 為無(wú)符號(hào) 64 位整型變量,如果沒(méi)有聲明類型,a 將自動(dòng)被判斷為有符號(hào) 32 位整型變量,這對(duì)于 a 的取值范圍有很大的影響。
重影的概念與其他面向?qū)ο笳Z(yǔ)言里的"重寫(xiě)"(Override)或"重載"(Overload)是不一樣的。重影就是剛才講述的所謂"重新綁定",之所以加引號(hào)就是為了在沒(méi)有介紹這個(gè)概念的時(shí)候代替一下概念。
重影就是指變量的名稱可以被重新使用的機(jī)制:
fn main() { let x = 5; let x = x + 1; let x = x * 2; println!("The value of x is: {}", x); }
這段程序的運(yùn)行結(jié)果:
The value of x is: 12
重影與可變變量的賦值不是一個(gè)概念,重影是指用同一個(gè)名字重新代表另一個(gè)變量實(shí)體,其類型、可變屬性和值都可以變化。但可變變量賦值僅能發(fā)生值的變化。
let mut s = "123"; s = s.len();
這段程序會(huì)出錯(cuò):不能給字符串變量賦整型值。