0Pricing
Learn Rust Coding · บทเรียน

String เทียบกับ &str

ความเป็นเจ้าของข้อความ

String เทียบกับ &str เป็นบทเรียน Learn Rust Coding ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Learn Rust Coding และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน

ข้อความแบบมีเจ้าของเทียบกับข้อความแบบยืม

Rust แยกการเป็นเจ้าของข้อความออกเป็นสองชนิด:

  • String — เป็นเจ้าของข้อมูลบนฮีป
  • &str — ยืมมุมมองของข้อความที่ไม่ได้เป็นเจ้าของ
fn main() {
    let owned = String::from("I own this");
    let borrowed: &str = "I am borrowed";
    println!("{} / {}", owned, borrowed);
}

ข้อมูลอยู่ที่ใด

String จัดเก็บไบต์ไว้บนฮีปและสามารถขยายได้ ส่วนลิเทอรัลข้อความ &str จะถูกฝังอยู่ในไบนารีของโปรแกรมและมีขนาดตายตัว

fn main() {
    let mut heap = String::from("grows");
    heap.push_str(" bigger");
    let fixed = "never changes";
    println!("{} | {}", heap, fixed);
}

การเป็นเจ้าของหมายถึงความรับผิดชอบ

เจ้าของ String จะคืนหน่วยความจำเมื่อค่าหลุดออกจากขอบเขตการใช้งาน ส่วน &str ไม่ได้เป็นเจ้าของสิ่งใด จึงไม่คืนหน่วยความจำใด ๆ

fn main() {
    {
        let s = String::from("temporary");
        println!("{}", s);
    } // s is dropped and its memory freed here
    println!("done");
}

การยืม String

คุณสามารถยืม String เป็น &str ได้โดยใช้ & โดย String ยังคงเป็นเจ้าของข้อมูล ส่วนสไลซ์เพียงแค่อ่านข้อมูลนั้น

fn main() {
    let owned = String::from("shared text");
    let view: &str = &owned;
    println!("{} / {}", owned, view);
}

การย้าย String

การกำหนด String ให้กับตัวแปรอื่นจะย้ายความเป็นเจ้าของไป ตัวแปรเดิมจึงไม่สามารถใช้งานได้อีก

fn main() {
    let a = String::from("hello");
    let b = a; // ownership moves to b
    // println!("{}", a); // would error: a was moved
    println!("{}", b);
}

การโคลนเพื่อเก็บไว้ทั้งสองค่า

หากต้องการสตริงที่มีเจ้าของสองค่าและแยกจากกันอย่างอิสระ ให้ใช้ clone เพื่อคัดลอกข้อมูล

fn main() {
    let a = String::from("hello");
    let b = a.clone();
    println!("{} and {}", a, b);
}

การคัดลอก &str มีต้นทุนต่ำ

&str เป็นเพียงพอยน์เตอร์และความยาว ดังนั้นการคัดลอกจึงไม่คัดลอกข้อความเบื้องหลัง นอกจากนี้ยังใช้คุณลักษณะ Copy ได้

fn main() {
    let original = "data";
    let copy = original; // both still valid
    println!("{} {}", original, copy);
}

ฟังก์ชันกับความเป็นเจ้าของ

การส่ง String แบบส่งค่าจะย้ายค่าเข้าไปในฟังก์ชัน ส่วนการส่ง &str หรือ &String เป็นเพียงการยืม ทำให้ค่าของผู้เรียกยังใช้งานได้

fn length(s: &str) -> usize {
    s.len()
}

fn main() {
    let text = String::from("measure me");
    println!("{}", length(&text));
    println!("still here: {}", text);
}

การคืนสตริงที่มีเจ้าของ

เมื่อฟังก์ชันต้องสร้างข้อความใหม่ ฟังก์ชันจะคืนค่า String ที่มีเจ้าของ เพื่อให้ผู้เรียกรับความเป็นเจ้าของไป

fn make_greeting(name: &str) -> String {
    format!("Hello, {}!", name)
}

fn main() {
    let g = make_greeting("Rust");
    println!("{}", g);
}

การเลือกชนิดที่เหมาะสม

แนวทาง:

  • ต้องการจัดเก็บข้อความที่มีเจ้าของใช่หรือไม่ ใช้ String
  • เพียงต้องการอ่านหรือส่งต่อข้อความใช่หรือไม่ รับค่าเป็น &str
  • ต้องการสร้างข้อความใหม่ในฟังก์ชันใช่หรือไม่ คืนค่าเป็น String
fn first_word(s: &str) -> &str {
    s.split_whitespace().next().unwrap_or("")
}

fn main() {
    let sentence = String::from("learn rust today");
    println!("{}", first_word(&sentence));
}

เหตุใดความแตกต่างนี้จึงสำคัญ

การแยกนี้ช่วยให้ Rust หลีกเลี่ยงการคัดลอกที่ไม่จำเป็น และรับประกันความปลอดภัยของหน่วยความจำโดยไม่ต้องใช้ตัวเก็บขยะ คุณจึงทราบได้เสมอว่าใครเป็นเจ้าของข้อความส่วนหนึ่ง

fn main() {
    let owned = String::from("safe");
    let borrowed = &owned[..];
    println!("owner {} borrows {}", owned, borrowed);
}

ตรวจสอบอย่างรวดเร็ว

ทบทวนว่าเกิดอะไรขึ้นเมื่อคุณย้าย String

สรุปทบทวน

ความเป็นเจ้าของของ String เทียบกับ &str:

  • String เป็นเจ้าของข้อมูลบนฮีปและคืนข้อมูลเมื่อถูกทิ้ง
  • &str ยืมข้อความที่มีอยู่และไม่ได้เป็นเจ้าของสิ่งใด
  • การย้าย String ทำให้ตัวแปรเดิมใช้ไม่ได้ ส่วน clone จะคัดลอกค่า
  • รับค่าเป็น &str เพื่ออ่าน และคืนค่าเป็น String เพื่อสร้างข้อความใหม่
fn shout(s: &str) -> String {
    s.to_uppercase()
}

fn main() {
    let name = String::from("rust");
    let loud = shout(&name);
    println!("{} -> {}", name, loud);
}

คำถามที่พบบ่อย

บทเรียน “String เทียบกับ &str” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “String เทียบกับ &str” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Learn Rust Coding ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “String เทียบกับ &str”

ความเป็นเจ้าของข้อความ คุณปฏิบัติ Learn Rust Coding ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Learn Rust Coding หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Learn Rust Coding บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “String เทียบกับ &str” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Learn Rust Coding นี้ได้ไหม

ได้ บทเรียน Learn Rust Coding ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. String เทียบกับ &str
  2. สไลซ์
  3. เมธอดของสตริง
  4. UTF-8 และอักขระ
← กลับไปที่ Learn Rust Coding