iT邦幫忙

0

二、三天學一點點 Rust:來!變數遮蔽(shadowing)(6)

  • 分享至 

  • xImage
  •  

這邊補充一下前面變數類似的概念差異

✅ 為什麼 Rust 有「變數遮蔽(shadowing)」這個名詞?

let x = 5;
let x = x + 1;

這不是單純的「x 改值」,而是:
第二個 let x = ... 是重新宣告一個「新的變數」,遮蔽掉前一個 x。
也就是說:
第一個 x 活在前一個 scope 中
第二個 x 則是新的變數,雖然名字相同,但其實是 全新的 x
📌 它被稱為 「遮蔽(shadowing)」,就是因為:
舊的變數還在作用域中,但它的名字已經被新的覆蓋(像被陰影遮住一樣)

✅ 這在 Rust 中是合法甚至鼓勵的寫法:

let spaces = "   ";
let spaces = spaces.len(); // 將字串變成整數

🔍 和 Python / JavaScript 的差異

🔸 Python 的寫法:

x = 5
x = x + 1

➡️ 是同一個變數 x 的值被改變(mutable by default)

  • 沒有 let 關鍵字
  • 不會重新宣告變數
  • Python 只有賦值(assignment),沒有 shadowing 的概念

🔸 JavaScript 的情況(視關鍵字而定)
用 let 或 const 時:

let x = 5;
let x = x + 1;  // ❌ 會報錯:Identifier 'x' has already been declared

JavaScript 不允許在同一個 block 裡用 let 宣告同名變數(不像 Rust)。

用 var 時:

var x = 5;
var x = x + 1;  // 合法,但其實只是被覆蓋了(非 block-scope)

但 var 是 function-scope,不是 block-scope,風險大且不建議用。

✅ Rust 為何支援 Shadowing?

Rust 支援 shadowing 的目的有幾個:

  • 可以改變變數的「型別」:
let x = "123";
let x = x.parse::<i32>().unwrap(); // 原本是 &str,後來變成 i32
  • 保持不可變(immutable)特性下的彈性
    你不需要 mut 就能重新定義變數值
    更安全、更簡潔

🦀 Rust / Python / JavaScript:變數遮蔽比較表

📌 Rust / Python / JavaScript 的變數遮蔽(Variable Shadowing)比較

語言 是否允許同名變數重新宣告 是否有「變數遮蔽」語意 行為描述
Rust ✅ 可以,會產生新變數 ✅ 有 重新定義一個變數,舊變數仍存在但被遮蔽
Python ✅ 可以,但只是改值 ❌ 沒有 修改原本的變數值,並非新變數
JavaScript let 不行,var ❌ 沒有 重新賦值,非 shadowing;使用 let 會報錯

✅ Rust 支援 shadowing 是為了語意清楚與型別轉換彈性。


變數遮蔽(shadowing) vs 可變變數(mut)

✅ 使用 mut:

let mut count = 1;
count = count + 1;
println!("{}", count); // 2

這裡是 同一個變數 count,被賦予新值。

✅ 使用 shadowing:

let count = 1;
let count = count + 1;
println!("{}", count); // 2

這裡是 重新宣告一個新的 count,前一個 count 被遮蔽掉(shadowed)

✅ 差異的關鍵點:型別可否改變?

let spaces = "   ";
let spaces = spaces.len(); // ✅ OK:由 &str → usize(shadowing)

let mut spaces = "   ";
spaces = spaces.len();     // ❌ 錯誤:mut 無法改變型別

🦀 Rust:變數遮蔽(shadowing) vs 可變變數(mut)比較

🔍 Rust 中:變數遮蔽(shadowing) vs 可變變數(mut)

比較項目 shadowing(變數遮蔽) mut(可變變數)
宣告方式 let x = 5; let x = x + 1; let mut x = 5; x = x + 1;
是否建立新變數 ✅ 是(重新宣告) ❌ 否(改變原變數)
是否可改變型別 ✅ 可以(例:&str → usize ❌ 不可以(型別需一致)
是否可變性切換 ✅ 可從 immutable ➝ mutable ❌ 不可變更 mut 狀態
適用情境 型別轉換、階段性處理、語意更清楚 值需改變但型別不變的情境
常見風格 函數式風格 命令式風格(imperative)

✅ Shadowing 讓你不用 mut 就能改變值與型別,更偏向安全的重新定義。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言