Rust 從入門到精通04-變數
- 2022 年 8 月 4 日
- 筆記
- Rust, Rust 從入門到精通
1、變數聲明語法
Rust 變數必須先聲明,後使用。
對於局部變數,常見是聲明語法為:
let variable : i32 = 100;
由於 Rust 是有自動推導類型功能的,所以後面的 :i32 是可以省略的。
1.1 語法解析更容易
局部變數聲明一定是以 let 開頭,類型一定是跟在冒號 : 的後面。語法歧義更少,語法分析器更容易編寫。
1.2 方便引入類型推導功能
Rust 聲明變數的特點:要聲明的變數前置,類型描述後置。
這是因為在變數聲明語句中,最重要的是變數本身,而類型其實是個附屬的額外描述,並非必不可少的部分。如果我們可以通過上下文環境由編譯器自動分析出這個變數的類型,那麼這個類型描述完全可以省略不寫。
PS:Rust 支援類型推導,在編譯器能夠推導類型的情況下,變數類型一般可以省略,但常量(const)和靜態變數(static)必須聲明類型。
Rust 從一開始就考慮了類型自動推導功能,因此類型後置的語法更加合適。
1.3 模式解構
pattern destructure
比如將變數由只讀變為可讀寫(mut聲明)
2、變數命名規則
Rust 里的合法標識符(包括變數名、函數名、trait名等)必須由:
①、數字
②、字母
③、下劃線
注意:不能以數字開頭!!!
另外:要注意下劃線 _ 的特殊用法。
3、變數遮蔽
Rust 允許在同一個程式碼塊中聲明同樣名字的變數,後面聲明的變數會將前面聲明的變數「遮蔽」起來。
//變數遮蔽
fn variable_masking(){
let x = "123";
println!("{}",x);
let x = 1;
println!("{}",x);
}
注意:這樣做並不會產生記憶體安全問題,因為我們對這塊記憶體擁有完整的所有權,且此時並沒有任何其它引用指向這個變數,對這個變數的修改是完全合法的。
4、變數類型推導
Rust的類型推導有兩種:
①、從變數聲明的當前語句中獲取資訊進行推導
②、通過上下文資訊進行推導
//類型推導
fn type_derivation(){
//1.1 沒有明確標出變數類型,但是通過字面量的後綴,編譯器知道x的類型是 u8
let x = 5u8;
//1.2 通過字面量值 1,編譯器知道y 的類型是 i32
let y = 1;
//1.3 創建一個動態數組,但是沒有聲明數組裡面是什麼類型
let mut vec = Vec::new();
//編譯器通過添加的元素 1 ,推導出 vec 的實際類型是 Vec<i32>
vec.push(1);
println!("{}",x);
println!("{}",y);
println!("{:?}",vec);
}
5、類型別名
通過 type 關鍵字給同一個類型起個別名。
//類型別名
fn type_alias(){
//將 i32 這種數據類型起別名為 int
type int = i32;
let x : int = 1;
println!("{}",x);
}
類型別名還可以用於泛型場景:
type Double
= (T,Vec );
那麼,以後使用 Double
6、不可變 mut
Rust 聲明的變數默認是不可變的。
默認不可變,這是一個很重要的特性,它符合最小許可權原則,有助於我們寫出正確且健壯的程式碼。
// 變數不可變
fn variable_mut(){
let i = 123;
i = 2;
}
編譯報錯:
如果要使得變數可變,必須要用關鍵字 mut
聲明:
fn variable_mut(){
let mut i = 123;
i = 2;
}
當你使用 mut 卻沒有修改變數,Rust 編譯期會友好地報警,提示你移除不必要的 mut。
fn main() {
variable_mut();
}
// 變數不可變
fn variable_mut(){
let mut i = 123;
println!("{}",i);
}
編譯器警告:
7、靜態變數
Rust 中通過 static 關鍵字聲明靜態變數,如下:
static GLOBAL : i32 = 0;
static 聲明的變數的生命周期是整個程式,從啟動到退出,static 變數的生命周期永遠是 『static』,它佔用的記憶體空間也不會在執行過程中被回收。
這也是 Rust 中唯一聲明全局變數的方法。
由於 Rust 非常注重記憶體安全,因此全局變數的使用有很多限制:
①、全局變數必須在聲明的時候馬上初始化(對應局部變數可以先聲明不初始化,只需要保證使用的時候初始化就行了,我們可以這樣理解,全局變數是寫在函數外面,而局部變數是寫在函數內部,所以需要保證全局變數聲明的時候就要初始化);
②、全局變數的初始化必須是編譯期可確定的常量,不能包括執行期才能確定的表達式、語句和函數調用;
③、帶有 mut 修飾的全局變數,在使用的時候必須使用 unsafe 關鍵字。
8、常量
Rust 中通過 const 關鍵字聲明常量。如下:
const GLOBAL : i32 = 0;
①、使用 const 聲明的是常量,而不是變數。因此不允許使用 mut 關鍵字修飾這個變數綁定。
②、常量的初始化表達式也一定要是一個編譯期確定的常量,不能是運行期的值。
注意:const 和 static 最大的區別在於編譯器並不一定會給 const 常量分配記憶體空間,在編譯過程中,它很可能會被內聯優化。
9、變數聲明常見錯誤
9.1 變數必須初始化才能使用
類型沒有默認構造函數,變數值沒有「默認值」
fn main() {
let x : i32;
println!("{}",x);
}
9.2 不能通過 mut 關鍵字修飾 const 聲明的變數
這個很容易理解,常量是不可變的,mut 表示可變,放一起語義衝突了。
//mut和 const 不能一起使用
fn const_mut_error(){
const mut i : i32 = 1;
println!("{}",i);
}