(明明就超過一個禮拜
這次主題應該偏簡單
會介紹變數 (Variable)、常數 (Constant)、Static Variable、Shadowing (遮蔽)
相對於地上的我們,天上星星的存在是接近永恆不變的變與不變的道理....請參考前赤壁賦 (不要玩古文x
Photo by John Fowler on Unsplash |
變數
不可變 (Immutable)
首先為何要提變與不變呢?因為 Rust 中的變數預設是不可變
不可變?! 那還叫變數?
是,就它預設是這樣不然是要 @#%&
當一個變數不可變時就像是把數值綁定到一個名稱上一樣
預設不可變,主要有兩個好處:更安全、能更簡單使用 Rust 提供的並行處理 (concurrency)
實際上的不變是怎樣呢? 那就上 code 囉 OuO
首先 let 是宣告變數的關鍵字
let x = 5; // 把 5 綁定到 x 上
錯誤操作:更改不可變的變數
fn main() { let x = 5; println!("x: {}", x); x = 6; // 改變不可變 x --> ERROR println!("x: {}", x); }
編譯器在編譯時期會報錯:
這裡會發現....Rust 的編譯器會不會太囉嗦,把所有相關錯誤的位置都列出來
因此有人說寫 Rust 其實是編譯器在教怎麼寫 OuO
error[E0384]: cannot assign twice to immutable variable `x` --> t.rs:4:5 | 2 | let x = 5; | - first assignment to `x` 3 | println!("The value of x is: {}", x); 4 | x = 6; | ^^^^^ cannot assign twice to immutable variable
那這個錯誤要怎麼改呢?
第一種解法就是不要寫 x = 6; 那行 (這不是廢話
第二種就是....
可變變數 (Mutable Variable)
是不是感覺有點奇怪,一開始就用這個就不會有問題啦!?但是預設 (這裡指不可變) 是什麼其實很重要
因為人寫程式都傾向於使用預設,所以這樣設計時,就會不知不覺使用更安全的方式
等到預設無法滿足需求時,再去使用非預設
使用 mut
let mut x = 5; // 把 5 綁定到 x 上,且 x 為可變
這樣下面的 code 就會過了 OuO
fn main() { let mut x = 5; println!("x: {}", x); x = 6; // 可以改變 x 了!!!! println!("x: {}", x); }
除了變數當然就還有....
常數 (Constant)
使用 const必須宣告型別,並給初始值
不能使用 mut:常數不是預設不可變,是永遠不可變 (真●星星
只能由表達式賦值,不能是函式呼叫的結果、執行時期得到的值
整個執行時期都是有效的 (可定義在全域
命名慣例是使用全大寫英文,並使用底線連接單字
const MAX_POINTS: u32 = 100_000;
Static Variabe
大部分跟常數頗像,必須宣告型別,並給初始值,命名慣例....但是有固定的記憶體存放此數值 (常數沒有
不過 static 可以有 mut,但是對可變的 static 變數操作時需要用 unsafe 的區塊包住
(看到 unsafe 就有點怕 w
其實要用 unsafe 是因為 static 變數是所有執行緒都可以存取的
此時變數若為可變,代表可能同時有多個執行緒改值,所以用 unsafe 警告這個區塊有危險
static N: i32 = 5;
static mut N: i32 = 5; unsafe { N += 1; println!("N: {}", N); }
Shadowing (遮蔽)
(不知道該不該翻成遮蔽首先看一下這段程式碼:(註解部分是輸出的結果)
fn main() { let x = 5; println!("x: {}", x); // x: 5 { let mut x = x; x += 1; println!("x: {}", x); // x: 6 } println!("x: {}", x); // x: 5 }
內部區塊 (scope) 的 x 會遮蔽上一層的 x,離開區塊後不會影響外部的 x
此外也可以遮蔽同一層變數,只是被遮蔽者其數值就會被刪掉,因為沒有綁定到任何變數上
此特性有很多可以應用的地方,甚至可以轉換型別,因為是重新綁定
例如不用重新想名稱 (Hardest tasks for Programmers....)
像是官網以下面計算空白字串為例
fn main() { let spaces = " "; // 此字串只會用一次不需要儲存 let spaces = spaces.len(); // 遮蔽,型別變成整數 println!("{} 個空白", spaces); }
下篇簡單說個型別
參考資料:
Variables and Mutability
const and static
沒有留言:
張貼留言