จากบทความก่อน ผมได้บอกไว้ว่าในภาษา Rust นั้น String ไม่ได้เป็น Data Types ทั่วไป แต่เราจะมองว่า String นั้นเป็นกลุ่มของ Characters เลย มันเลยมองการเก็บข้อมูลได้เป็น 2 แบบ คือ แบบ Stack Memory และแบบ Heap Memory ซึ่งมีผลกับ performance ในการใช้งานมัน ซึ่งไว้ค่อยอธิบายในอนาคต
เพราะฉนั้นเราสามารถประกาศตัวแปร string ได้ 2 ประเภท คือ
String literal immutable
การประกาศตัวแปรแบบ immutable นั้น เราจะใช้ &str
ในการระบุ type
fn main() {
let text: &str = "Hello, world!";
println!("Say {}", text);
}
String literal immutable
แน่นอนว่าถ้าหากเราอยากจะเปลี่ยนข้อมูลในตัวแปร text
นั้น เราจะต้องเพิ่ม mut
ไว้หน้าตัวแปร let
เช่นเดียวกับตัวแปรอื่นๆ
fn main() {
let mut text: &str = "Hello, world!";
if text == "Hello, world!" {
text = "Hello, Rustsssss";
}
println!("Say {}", text);
}
edit text in parameter
แต่ว่า การประกาศตัวแปรแบบ immutable นั้น ไม่สามารถแก้ไข element ของ string ได้ อ่านตอนแรกก็แอบงงนิดๆ ว่า ไอ้โค๊ดด้านบนมันก็แก้ไขได้นะ
เลยลองใช้หลายๆ แบบดูเลย เข้าใจเพิ่มขึ้นมานิดนึง คือ
การประกาศแบบนี้นั้น ไม่สามารถมารถแก้ไข element ได้จริงๆ ซึ่งการแก้ไข element ก็อย่างเช่น
fn main() {
let mut text: &str = "Hello, world!";
if text == "Hello, world!" {
text = "Hello, Rustsssss".to_lowercase();
}
println!("Say {}", text);
}
add to_lowercase
ถ้าเราอยากจะเปลี่ยน text ให้เป็นตัวพิมพ์เล็กทั้งหมด มันก็จะบอกว่าทำไม่ได้ mismatched types
เท่าที่เข้าใจคือ มันแก้ ข้อความในตัวแปรได้เท่านั้น ไป element (องค์ประกอบ) ภายในของมันไม่ได้
เหตุผลที่เป็นอย่างนั้นเพราะว่าจริงๆ แล้ว การประการ &str
แบบนี้ เป็นการทำ String slice
นั่นเอง
การใช้งาน &str
มันจะได้เรื่อง overhead ที่น้อยกว่าอีกแบบหนึ่ง เหมาะกับการใช้งานทั่วไป เก็บค่า string ที่ไม่ค่อยมีการเปลี่ยนแปลง และสามารถการส่งค่า string ไปยัง function ที่ต้องการได้ (pass by value) ซึ่งต่างอีกตัวนึง
String mutable
ตรงตัวเลยเป็น string ที่เราสามารถแก้ไขหรือทำอะไรกับมันก็ได้ การประกาศก็จะแปลกๆ ตาหน่อย นั่นคือ String::from("text")
fn main() {
let name = String::from("Rust");
println!("Say {}", name.to_uppercase());
}
String mutable and edit element
สังเกตว่า เราสามารถใช้ฟังก์ชั่น to_uppercase()
ได้แล้ว จริงๆ แล้วเรายังมีคำสั่งอื่นๆ ให้ใช้อีก เช่น
len()
: ความยาวของ stringis_empty()
: string ว่างหรือไม่contains()
: ค้นหา substringto_uppercase()
: แปลงเป็นตัวพิมพ์ใหญ่to_lowercase()
: แปลงเป็นตัวพิมพ์เล็ก
การใช้งาน String
มันจะมี overhead ที่มากกว่าอีกแบบแรก และเหมาะสำหรับการใช้งานที่ต้องการแก้ไข string บ่อยๆ หากเราต้องการที่จะเก็บค่า string ที่มีการเปลี่ยนแปลง หรือต้องมีการแปลง string ก็ให้ใช้ตัวนี้
ส่วนวิธีการส่งค่าไปยัง function อื่นจะอยู่ในรูปแบบของการ pass by reference แทน