Vec และ String
Vec<T> — Array บน Heap ที่ขยายได้
หัวข้อที่มีชื่อว่า “Vec<T> — Array บน Heap ที่ขยายได้”Vec<T> คือ Collection ลำดับที่ใช้งานหลักใน Rust เก็บ Element ของประเภท T อย่าง Contiguous บน Heap และปรับขนาดโดยอัตโนมัติเมื่อคุณ Push เกิน Capacity ปัจจุบัน
let mut v: Vec<i32> = Vec::new(); // Vec ว่างเปล่าlet w = vec![1, 2, 3]; // Macro vec! แบบย่อPush, Pop และ Index
หัวข้อที่มีชื่อว่า “Push, Pop และ Index”let mut v = vec![10, 20, 30];
v.push(40); // เพิ่ม Element ท้ายสุดlet last = v.pop(); // ลบและคืน Element ท้ายสุด → Some(40)let first = v[0]; // Index — Panic ถ้าเกิน Boundslet safe = v.get(100); // คืน Option<&T> — None ถ้าเกิน Boundsควรใช้ .get(i) เมื่อ Index อาจเกิน Range เพื่อจัดการกรณี None แทนที่จะ Panic
การ Iterate ผ่าน Vec
หัวข้อที่มีชื่อว่า “การ Iterate ผ่าน Vec”let nums = vec![1, 2, 3];
for n in &nums { // ยืม Element แต่ละตัวเป็น &i32 println!("{}", n);}
// nums ยังใช้ได้หลัง Loop เพราะเราแค่ยืมมันการใช้ &nums ยืม Vector; การใช้ nums จะย้าย (Move) และทำให้ใช้ไม่ได้หลัง Loop
String — ข้อความที่เป็นเจ้าของและขยายได้
หัวข้อที่มีชื่อว่า “String — ข้อความที่เป็นเจ้าของและขยายได้”String คือประเภทข้อความบน Heap ที่ Mutable ของ Rust เป็นเจ้าของ Byte ของตัวเองและจัดการการ Deallocation
let mut s = String::from("hello");s.push(' '); // Push ตัวอักษรเดียวs.push_str("world"); // ต่อท้าย String Slicelet combined = s + " again"; // + ย้าย s และต่อท้ายString เทียบกับ &str
หัวข้อที่มีชื่อว่า “String เทียบกับ &str”String | &str | |
|---|---|---|
| Ownership | เป็นเจ้าของ | Borrowed Slice |
| ตำแหน่ง | Heap | Stack / Static / ภายใน String |
| Mutable | ได้ (ด้วย mut) | ไม่ได้ |
| การใช้งานทั่วไป | สร้าง/แก้ไขข้อความ | อ่านข้อความ |
&String จะถูก Coerce เป็น &str โดยอัตโนมัติ ดังนั้นควรใช้ &str ใน Parameter ของ Function เพื่อความยืดหยุ่นสูงสุด
fn shout(s: &str) -> String { s.to_uppercase()}
let owned = String::from("hello");shout(&owned); // &String ถูก Coerce เป็น &strshout("world"); // String Literal เป็น &str อยู่แล้วfn main() { // Vec<i32> basics let mut nums: Vec<i32> = Vec::new(); nums.push(10); nums.push(20); nums.push(30); println!("len={}, first={}", nums.len(), nums[0]);
// pop returns Option<T> let last = nums.pop(); println!("popped: {:?}, remaining: {:?}", last, nums);
// safe get returns Option<&T> println!("get(5) = {:?}", nums.get(5));
// iterate by reference — nums still valid after for n in &nums { println!("item: {}", n); } println!("nums still valid: {:?}", nums);
// String vs &str let literal: &str = "hello"; let mut owned: String = String::from(literal); owned.push_str(" world"); println!("{}", owned);
// slice into a String let slice: &str = &owned[0..5]; println!("slice: {}", slice);}Compiling…