# Rust: พื้นฐานสำหรับนักพัฒนาที่มีประสบการณ์ในปี 2026 > เรียนรู้ Rust ได้อย่างรวดเร็วโดยอาศัยความรู้ด้านการเขียนโปรแกรมที่มีอยู่ Ownership, borrowing, lifetimes และ pattern ที่จำเป็นอธิบายไว้สำหรับนักพัฒนาที่มาจาก C++, Java หรือ Python - Published: 2026-01-09 - Updated: 2026-04-01 - Author: Anthony Fillion-Maillet - Tags: rust, systems programming, ownership, memory safety, performance - Reading time: 14 min --- Rust ยังคงได้รับความนิยมเพิ่มขึ้นอย่างต่อเนื่องในทุกปี และเหตุผลนั้นชัดเจน: การรับประกันความปลอดภัยของหน่วยความจำในเวลาคอมไพล์ ประสิทธิภาพระดับเดียวกับ C++ และระบบนิเวศที่ทันสมัย สำหรับนักพัฒนาที่มีประสบการณ์จาก C++, Java หรือ Python การเรียนรู้ Rust อาจรู้สึกสับสนในตอนแรก แต่แนวคิดพื้นฐานจะกลายเป็นสิ่งที่เข้าใจได้อย่างเป็นธรรมชาติเมื่อเข้าใจอย่างถ่องแท้แล้ว > **ทำไมต้อง Rust ในปี 2026?** > > Rust ครองตำแหน่งภาษาที่นักพัฒนาชื่นชอบมากที่สุดบน Stack Overflow ติดต่อกัน 8 ปี ถูกนำไปใช้โดย Microsoft, Google, Amazon และ Meta สำหรับส่วนประกอบที่สำคัญ Rust มอบความปลอดภัยของหน่วยความจำโดยไม่ต้องใช้ garbage collector ## การตั้งค่าสภาพแวดล้อม Rust ก่อนเริ่มเขียนโค้ด จำเป็นต้องติดตั้ง Rust ผ่าน rustup ซึ่งเป็นเครื่องมือจัดการเวอร์ชันอย่างเป็นทางการ ```bash # install.sh # Install Rust via rustup (macOS, Linux) curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Verify installation rustc --version cargo --version ``` Cargo คือตัวจัดการแพ็กเกจและเครื่องมือ build ของ Rust โดย Cargo รวมฟังก์ชันการทำงานของ npm, Maven และ Make ไว้ในเครื่องมือเดียวที่สอดคล้องกัน ```bash # project-setup.sh # Create a new project cargo new my_project cd my_project # Generated structure: # my_project/ # ├── Cargo.toml # Manifest (like package.json) # └── src/ # └── main.rs # Entry point # Essential commands cargo build # Compile the project cargo run # Compile and run cargo test # Run tests cargo check # Check without building (faster) ``` ## ตัวแปรและความไม่เปลี่ยนแปลงโดยค่าเริ่มต้น Rust กลับด้านแนวปฏิบัติทั่วไป: ตัวแปร**เป็น immutable โดยค่าเริ่มต้น** แนวทางนี้บังคับให้นักพัฒนาคิดอย่างชัดเจนเกี่ยวกับ mutability และป้องกันบั๊กได้หลายประเภท ```rust // variables.rs fn main() { // Immutable by default let x = 5; // x = 6; // Compile error! // Explicitly mutable variable let mut y = 5; y = 6; // OK // Shadowing: redeclaration in the same scope let x = x + 1; // Creates a new variable x let x = x * 2; // x is now 12 // Shadowing also allows changing the type let spaces = " "; // &str let spaces = spaces.len(); // usize } ``` > **Shadowing กับ Mutability** > > Shadowing สร้างตัวแปรใหม่ ซึ่งต่างจาก `mut` ที่เปลี่ยนแปลงค่าของตัวแปรเดิม Shadowing อนุญาตให้แปลงค่าในขณะที่ยังคงรักษาชื่อตัวแปรที่ชัดเจนไว้ได้ ## ชนิดข้อมูลพื้นฐาน Rust เป็นภาษาแบบ statically typed ที่มีความสามารถในการอนุมานชนิดข้อมูลที่ยอดเยี่ยม ต่อไปนี้คือชนิดข้อมูล primitive ที่จำเป็นต้องรู้ ```rust // types.rs fn main() { // Signed integers: i8, i16, i32, i64, i128, isize let age: i32 = 30; // Unsigned integers: u8, u16, u32, u64, u128, usize let count: u64 = 1_000_000; // Underscores for readability // Floats: f32, f64 (default) let pi: f64 = 3.14159; // Boolean let active: bool = true; // Unicode character (4 bytes) let emoji: char = '🦀'; // Tuple: fixed collection of different types let person: (String, i32) = (String::from("Alice"), 28); let (name, age) = person; // Destructuring // Array: fixed size, same type let numbers: [i32; 5] = [1, 2, 3, 4, 5]; let first = numbers[0]; // Slice: view into a portion of data let slice: &[i32] = &numbers[1..4]; // [2, 3, 4] } ``` ## Ownership: แนวคิดที่เปลี่ยนแปลงวงการ Ownership คือนวัตกรรมหลักของ Rust ระบบนี้รับประกันความปลอดภัยของหน่วยความจำโดยไม่ต้องใช้ garbage collector แลกกับเส้นทางการเรียนรู้ในช่วงเริ่มต้น ### กฎสามข้อของ Ownership ```rust // ownership.rs fn main() { // Rule 1: Each value has a single owner let s1 = String::from("hello"); // Rule 2: When the owner goes out of scope, the value is freed { let s2 = String::from("world"); // s2 is valid here } // s2 is dropped, no longer accessible // Rule 3: Only one ownership at a time (move) let s3 = s1; // s1 is MOVED to s3 // println!("{}", s1); // Error: s1 is no longer valid! println!("{}", s3); // OK: s3 is the owner } ``` ### Move และ Clone ```rust // move_clone.rs fn main() { // Simple types (stack): automatic Copy let x = 5; let y = x; // Copy, not move println!("x = {}, y = {}", x, y); // Both are valid // Complex types (heap): Move by default let s1 = String::from("hello"); let s2 = s1; // Move // s1 is no longer usable // Explicit clone to duplicate let s3 = String::from("world"); let s4 = s3.clone(); // Deep copy println!("s3 = {}, s4 = {}", s3, s4); // Both valid } ``` > **Move กับฟังก์ชัน** > > การส่งค่าไปยังฟังก์ชันจะทำให้ ownership ถูกโอนย้าย ฟังก์ชันจะกลายเป็นเจ้าของ และค่านั้นจะไม่สามารถเข้าถึงได้หลังจากเรียกใช้ เว้นแต่จะถูกส่งคืน ```rust // ownership_functions.rs fn main() { let s = String::from("hello"); takes_ownership(s); // println!("{}", s); // Error: s has been moved let x = 5; makes_copy(x); println!("{}", x); // OK: i32 implements Copy // To regain ownership, return the value let s2 = String::from("hello"); let s3 = takes_and_gives_back(s2); println!("{}", s3); // OK } fn takes_ownership(s: String) { println!("{}", s); } // s is dropped here fn makes_copy(x: i32) { println!("{}", x); } fn takes_and_gives_back(s: String) -> String { s // Returns ownership } ``` ## Borrowing: การอ้างอิงโดยไม่โอนความเป็นเจ้าของ Borrowing อนุญาตให้ใช้ค่าโดยไม่ต้องรับ ownership กลไกนี้เป็นสิ่งที่ถูกใช้บ่อยที่สุดใน Rust ```rust // borrowing.rs fn main() { let s1 = String::from("hello"); // Immutable reference: read-only let len = calculate_length(&s1); println!("Length of '{}': {}", s1, len); // s1 still valid // Mutable reference: modification allowed let mut s2 = String::from("hello"); change(&mut s2); println!("{}", s2); // "hello, world" } fn calculate_length(s: &String) -> usize { s.len() } // s goes out of scope but doesn't drop (it's a reference) fn change(s: &mut String) { s.push_str(", world"); } ``` ### กฎของ Borrowing ```rust // borrowing_rules.rs fn main() { let mut s = String::from("hello"); // Rule 1: Multiple immutable references simultaneously OK let r1 = &s; let r2 = &s; println!("{} and {}", r1, r2); // Rule 2: ONLY ONE mutable reference at a time let r3 = &mut s; // let r4 = &mut s; // Error: already borrowed mutably println!("{}", r3); // Rule 3: No mutable ref if immutable ref exists let r5 = &s; // let r6 = &mut s; // Error: r5 is still active println!("{}", r5); // Once r5 is used for the last time, mutable borrow is allowed let r7 = &mut s; // OK: r5 is no longer used after this r7.push_str("!"); } ``` ## Lifetimes: การรับประกันความถูกต้องของการอ้างอิง Lifetimes ช่วยให้มั่นใจว่า reference ยังคงถูกต้อง คอมไพเลอร์มักจะอนุมานได้โดยอัตโนมัติ แต่บางครั้งจำเป็นต้องมีการระบุ annotation อย่างชัดเจน ```rust // lifetimes_basic.rs // Classic error: reference to freed data // fn dangling() -> &String { // let s = String::from("hello"); // &s // Error: s will be dropped, invalid reference! // } // Solution: return the owned value fn no_dangle() -> String { let s = String::from("hello"); s // Ownership transferred, no problem } ``` ### Lifetime Annotations ```rust // lifetimes_annotation.rs // The compiler can't figure out which reference will be returned // fn longest(x: &str, y: &str) -> &str { ... } // Error! // Explicit annotation: return lives as long as BOTH x AND y fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } } fn main() { let string1 = String::from("long string"); let result; { let string2 = String::from("xyz"); result = longest(&string1, &string2); println!("Longest: {}", result); // OK here } // println!("{}", result); // Error: string2 dropped } ``` > **กฎการละเว้น Lifetime (Lifetime Elision)** > > Rust ใช้กฎ elision เพื่อหลีกเลี่ยงการเขียน annotation ในกรณีที่ไม่ซับซ้อน สำหรับผู้เริ่มต้น การทำตามข้อความแจ้งเตือนที่ชัดเจนจากคอมไพเลอร์ถือว่าเพียงพอ ## Struct และ Implementation Struct เป็นส่วนประกอบพื้นฐานสำหรับการสร้างชนิดข้อมูลแบบกำหนดเองใน Rust ```rust // structs.rs // Struct definition #[derive(Debug)] // Enables printing with {:?} struct User { username: String, email: String, active: bool, sign_in_count: u64, } // Implementation block for methods impl User { // Constructor (convention: fn new or descriptive name) fn new(username: String, email: String) -> Self { Self { username, email, active: true, sign_in_count: 1, } } // Method: takes &self (reference to instance) fn is_active(&self) -> bool { self.active } // Method with mutation: takes &mut self fn deactivate(&mut self) { self.active = false; } // Method consuming self (rare) fn into_username(self) -> String { self.username } } fn main() { let mut user = User::new( String::from("alice"), String::from("alice@example.com"), ); println!("Active: {}", user.is_active()); user.deactivate(); println!("Active: {}", user.is_active()); // Debug print println!("{:?}", user); } ``` ## Enum และ Pattern Matching Enum ใน Rust ทรงพลังกว่าภาษาส่วนใหญ่อย่างมาก เนื่องจากแต่ละ variant สามารถเก็บข้อมูลได้ ```rust // enums.rs // Simple enum enum Direction { North, South, East, West, } // Enum with data (algebraic data type) enum Message { Quit, Move { x: i32, y: i32 }, Write(String), ChangeColor(u8, u8, u8), } impl Message { fn process(&self) { match self { Message::Quit => println!("Quitting"), Message::Move { x, y } => println!("Moving to ({}, {})", x, y), Message::Write(text) => println!("Writing: {}", text), Message::ChangeColor(r, g, b) => { println!("Color: rgb({}, {}, {})", r, g, b) } } } } fn main() { let msg = Message::Move { x: 10, y: 20 }; msg.process(); let msg2 = Message::Write(String::from("Hello Rust!")); msg2.process(); } ``` ### Option และ Result: การจัดการข้อผิดพลาด ```rust // option_result.rs use std::fs::File; use std::io::{self, Read}; fn main() { // Option: present or absent value (replaces null) let numbers = vec![1, 2, 3]; let first: Option<&i32> = numbers.first(); match first { Some(n) => println!("First: {}", n), None => println!("Empty list"), } // Utility methods let value = first.unwrap_or(&0); let doubled = first.map(|n| n * 2); // Result: success or error let result = read_file("config.txt"); match result { Ok(content) => println!("Content: {}", content), Err(e) => println!("Error: {}", e), } } fn read_file(path: &str) -> Result { let mut file = File::open(path)?; // ? propagates the error let mut content = String::new(); file.read_to_string(&mut content)?; Ok(content) } ``` > **ตัวดำเนินการ ?** > > ตัวดำเนินการ `?` เป็น syntactic sugar สำหรับการส่งต่อข้อผิดพลาด ตัวดำเนินการนี้จะส่งคืนข้อผิดพลาดโดยอัตโนมัติหาก Result เป็น Err และจะ unwrap ค่า Ok ในกรณีที่สำเร็จ ## Trait: Polymorphism แบบ Rust Trait กำหนดพฤติกรรมที่ใช้ร่วมกัน คล้ายกับ interface ใน Java หรือ protocol ใน Swift ```rust // traits.rs // Trait definition trait Summary { fn summarize(&self) -> String; // Method with default implementation fn preview(&self) -> String { format!("{}...", &self.summarize()[..50.min(self.summarize().len())]) } } struct Article { title: String, author: String, content: String, } struct Tweet { username: String, content: String, } // Implementation for Article impl Summary for Article { fn summarize(&self) -> String { format!("{} by {}", self.title, self.author) } } // Implementation for Tweet impl Summary for Tweet { fn summarize(&self) -> String { format!("@{}: {}", self.username, self.content) } } // Function accepting any type implementing Summary fn notify(item: &impl Summary) { println!("Breaking news: {}", item.summarize()); } // Equivalent syntax with trait bound fn notify_generic(item: &T) { println!("Breaking news: {}", item.summarize()); } fn main() { let article = Article { title: String::from("Rust 2026"), author: String::from("Community"), content: String::from("..."), }; let tweet = Tweet { username: String::from("rustlang"), content: String::from("Rust is awesome!"), }; notify(&article); notify(&tweet); } ``` ## Collection ที่จำเป็น Rust มี collection ที่ทรงพลังใน standard library ```rust // collections.rs use std::collections::HashMap; fn main() { // Vec: dynamic array let mut numbers: Vec = Vec::new(); numbers.push(1); numbers.push(2); numbers.push(3); // vec! macro for initialization let nums = vec![1, 2, 3, 4, 5]; // Iteration for n in &nums { println!("{}", n); } // Functional methods let doubled: Vec = nums.iter().map(|x| x * 2).collect(); let sum: i32 = nums.iter().sum(); let evens: Vec<&i32> = nums.iter().filter(|x| *x % 2 == 0).collect(); // String: growable UTF-8 string let mut s = String::from("Hello"); s.push_str(", World!"); s.push('!'); // Concatenation let s1 = String::from("Hello, "); let s2 = String::from("World!"); let s3 = s1 + &s2; // s1 moved, s2 borrowed // or with format! let s4 = format!("{}{}", "Hello, ", "World!"); // HashMap let mut scores: HashMap = HashMap::new(); scores.insert(String::from("Blue"), 10); scores.insert(String::from("Red"), 50); // Access with get (returns Option) if let Some(score) = scores.get("Blue") { println!("Blue: {}", score); } // Entry API for conditional insertion scores.entry(String::from("Yellow")).or_insert(25); } ``` ## การจัดการข้อผิดพลาดอย่างถูกวิธี การจัดการข้อผิดพลาดที่เหมาะสมเป็นสิ่งจำเป็นใน Rust ต่อไปนี้คือ pattern ที่แนะนำ ```rust // error_handling.rs use std::fs::File; use std::io::{self, Read}; use std::num::ParseIntError; // Define a custom error type #[derive(Debug)] enum AppError { Io(io::Error), Parse(ParseIntError), Custom(String), } // Implement From for automatic conversion impl From for AppError { fn from(err: io::Error) -> Self { AppError::Io(err) } } impl From for AppError { fn from(err: ParseIntError) -> Self { AppError::Parse(err) } } // Function returning Result with custom error fn read_number_from_file(path: &str) -> Result { let mut file = File::open(path)?; // io::Error -> AppError let mut content = String::new(); file.read_to_string(&mut content)?; let number: i32 = content.trim().parse()?; // ParseIntError -> AppError Ok(number) } fn main() { match read_number_from_file("number.txt") { Ok(n) => println!("Number: {}", n), Err(AppError::Io(e)) => println!("IO error: {}", e), Err(AppError::Parse(e)) => println!("Parse error: {}", e), Err(AppError::Custom(msg)) => println!("Error: {}", msg), } } ``` > **Crate ที่แนะนำ** > > สำหรับโปรเจกต์จริง crate `thiserror` (สำหรับ library) และ `anyhow` (สำหรับ application) ช่วยลดความซับซ้อนในการจัดการข้อผิดพลาดได้อย่างมาก ## การทดสอบใน Rust Rust มี testing framework ในตัวที่ถูกรวมเข้ากับภาษาโดยตรง ```rust // lib.rs pub fn add(a: i32, b: i32) -> i32 { a + b } pub fn divide(a: i32, b: i32) -> Result { if b == 0 { Err(String::from("Division by zero")) } else { Ok(a / b) } } // Test module (compiled only for `cargo test`) #[cfg(test)] mod tests { use super::*; #[test] fn test_add() { assert_eq!(add(2, 3), 5); } #[test] fn test_add_negative() { assert_eq!(add(-1, 1), 0); } #[test] fn test_divide_success() { assert_eq!(divide(10, 2), Ok(5)); } #[test] fn test_divide_by_zero() { assert!(divide(10, 0).is_err()); } #[test] #[should_panic(expected = "index out of bounds")] fn test_panic() { let v = vec![1, 2, 3]; let _ = v[99]; // Panic! } } ``` ## บทสรุป Rust นำเสนอแนวคิดที่เป็นเอกลักษณ์ซึ่งผสมผสานความปลอดภัยของหน่วยความจำเข้ากับประสิทธิภาพสูง แนวคิด ownership และ borrowing อาจรู้สึกจำกัดในตอนแรก แต่จะกลายเป็นสิ่งที่เป็นธรรมชาติเมื่อฝึกฝนอย่างสม่ำเสมอ คอมไพเลอร์ของ Rust เป็นผู้ช่วยที่ล้ำค่า เนื่องจากข้อความแจ้งเตือนข้อผิดพลาดของ Rust ได้รับการยอมรับว่าเป็นหนึ่งในข้อความที่ดีที่สุดในอุตสาหกรรม ### รายการตรวจสอบสำหรับการเริ่มต้น - ติดตั้ง Rust ผ่าน rustup และเชี่ยวชาญการใช้ Cargo - เข้าใจความแตกต่างระหว่าง immutability กับ explicit mutability - เชี่ยวชาญกฎสามข้อของ ownership - ฝึกฝน borrowing ด้วย reference `&` และ `&mut` - ใช้ `Option` และ `Result` แทน null และ exception - เขียน test ด้วย `#[test]` ชุมชน Rust เป็นชุมชนที่เป็นมิตรและมีทรัพยากรการเรียนรู้อย่างอุดมสมบูรณ์ หนังสือทางการ "The Rust Programming Language" สามารถอ่านได้ฟรีทางออนไลน์ ด้วยพื้นฐานที่แข็งแกร่งเหล่านี้ นักพัฒนาจะพร้อมสำหรับการสำรวจหัวข้อขั้นสูง เช่น async/await, macro และ WebAssembly --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/th/blog/rust/rust-basics-experienced-developers