ข้ามไปยังเนื้อหา

Variables & Mutability

เมื่อประกาศตัวแปรด้วย let ตัวแปรนั้นจะ immutable — คุณกำหนดค่าให้ใหม่ไม่ได้ นี่ไม่ใช่ข้อจำกัด แต่คือคุณสมบัติที่ตั้งใจออกแบบมา ความ immutable โดยค่าเริ่มต้นช่วยให้คอมไพเลอร์ตรวจจับการเปลี่ยนแปลงที่ไม่ได้ตั้งใจและวิเคราะห์โค้ดได้แม่นยำกว่า

fn main() {
let x = 5;
// x = 6; // error[E0384]: cannot assign twice to immutable variable `x`
println!("x = {}", x);
}

เพื่ออนุญาตให้เปลี่ยนค่าได้ ให้เพิ่ม mut หลัง let:

fn main() {
let mut y = 10;
y = 20; // อนุญาตเพราะ y เป็น mut
println!("y = {}", y);
}

Shadowing แตกต่างจาก mutation คุณ ประกาศใหม่ ตัวแปรที่มีชื่อเดิมด้วย let binding ใหม่ binding ใหม่จะ บดบัง ของเดิมตลอด scope ที่เหลือ คุณแม้แต่เปลี่ยน type ได้เมื่อ shadow

fn main() {
let z = 3;
let z = z * 2; // shadow z ตัวก่อนหน้า
let z = z + 1; // shadow อีกครั้ง
println!("z = {}", z); // 7
// Shadowing เปลี่ยน type ได้
let word = "hello";
let word = word.len(); // shadow ด้วย usize
println!("len = {}", word);
}

Shadowing ไม่เหมือน mut ด้วย mut คุณกำหนดค่าใหม่ให้ตัวแปรเดิม ด้วย shadowing คุณสร้างตัวแปรใหม่ที่มีชื่อเดียวกัน เมื่อ scope สิ้นสุด binding ด้านนอกจะกลับมามองเห็นได้อีกครั้ง

const ประกาศ ค่าคงที่ที่ compile time ต่างจาก let constants จะ:

  • ต้องการ annotation ของ type อย่างชัดเจน
  • ต้องกำหนดเป็น constant expression (ไม่ใช่ค่า runtime)
  • มีอายุตลอด scope ที่ถูกประกาศ
  • ใช้ SCREAMING_SNAKE_CASE ตามธรรมเนียม
const MAX_POINTS: u32 = 100_000;
const GRAVITY: f64 = 9.81;
fn main() {
println!("MAX_POINTS = {}", MAX_POINTS);
println!("GRAVITY = {}", GRAVITY);
}

เครื่องหมาย underscore ใน 100_000 คือ ตัวคั่นตัวเลข (numeric separator) เป็นเพียงการแสดงผล คอมไพเลอร์ไม่สนใจตัวคั่นนี้ ใช้เพื่อให้ตัวเลขขนาดใหญ่อ่านได้ง่ายขึ้น

fn main() {
let x = 5;
// x = 6; // error: cannot assign twice to immutable variable
let mut y = 10;
y = 20;
println!("y = {}", y);
// Shadowing: re-bind the same name
let z = 3;
let z = z * 2;
let z = z + 1;
println!("z = {}", z);
// Constants are always immutable and require a type annotation
const MAX_POINTS: u32 = 100_000;
println!("MAX_POINTS = {}", MAX_POINTS);
}
keyword mut ทำหน้าที่อะไร?
ความแตกต่างหลักระหว่าง shadowing และ mut คืออะไร?
อะไรที่จำเป็นต้องมีในการประกาศ const?
underscore ใน 100_000 มีความหมายอย่างไรต่อคอมไพเลอร์ Rust?