จากบทความก่อน ผมได้บอกไว้ว่าในภาษา 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(): ความยาวของ string
  • is_empty(): string ว่างหรือไม่
  • contains(): ค้นหา substring
  • to_uppercase(): แปลงเป็นตัวพิมพ์ใหญ่
  • to_lowercase(): แปลงเป็นตัวพิมพ์เล็ก

การใช้งาน String มันจะมี overhead ที่มากกว่าอีกแบบแรก และเหมาะสำหรับการใช้งานที่ต้องการแก้ไข string บ่อยๆ หากเราต้องการที่จะเก็บค่า string ที่มีการเปลี่ยนแปลง หรือต้องมีการแปลง string ก็ให้ใช้ตัวนี้

ส่วนวิธีการส่งค่าไปยัง function อื่นจะอยู่ในรูปแบบของการ pass by reference แทน