การเปลี่ยนแปลงค่าภายใน: RefCell, Cell
เรียนรู้เกี่ยวกับ `RefCell` และ `Cell` สำหรับการเปลี่ยนแปลงค่าภายใน ทำให้เข้าถึงข้อมูลแบบเปลี่ยนแปลงค่าได้ผ่านการอ้างอิงแบบไม่เปลี่ยนแปลงค่าอย่างปลอดภัย
การเปลี่ยนแปลงค่าภายใน: RefCell, Cell เป็นบทเรียน Learn Rust Coding ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Learn Rust Coding และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 3 บทเรียน
ความสามารถในการเปลี่ยนแปลงข้อมูลภายในคืออะไร
ใน Rust กฎการยืมมักป้องกันไม่ให้คุณมีการอ้างอิงแบบเปลี่ยนแปลงได้ไปยังข้อมูล หากคุณมีการอ้างอิงแบบอ่านอย่างเดียวไปยังข้อมูลนั้นอยู่แล้ว ซึ่งช่วยรับรองความปลอดภัยของข้อมูล
ความสามารถในการเปลี่ยนแปลงข้อมูลภายใน เป็นรูปแบบการออกแบบที่อนุญาตให้คุณเปลี่ยนแปลงข้อมูลได้ แม้จะมีเพียงการอ้างอิงแบบอ่านอย่างเดียวไปยังข้อมูลนั้น เปรียบเสมือนข้อยกเว้นที่มีการควบคุมจากกฎปกติของ Rust ซึ่งใช้ในสถานการณ์เฉพาะ
`Cell<T>`: สำหรับชนิดข้อมูลที่คัดลอกได้
ชนิดข้อมูล Cell<T> มอบความสามารถในการเปลี่ยนแปลงข้อมูลภายในสำหรับชนิดข้อมูลที่นำเทรต Copy ไปใช้ได้ เช่น จำนวนเต็ม ค่าบูลีน และอักขระ โดยทำงานด้วยการแทนที่ค่าภายใน
get(): ส่งคืนสำเนาของค่าภายในCellset(value): แทนที่ค่าภายในCellด้วยค่าใหม่
วิธีนี้เรียบง่ายและมีประสิทธิภาพสำหรับข้อมูลขนาดเล็กที่คัดลอกได้
การใช้ `Cell` เพื่อปรับปรุงค่า
นี่คือตัวอย่างพื้นฐานของ Cell โปรดสังเกตว่าเราสามารถเปลี่ยนค่าภายใน Cell ได้ แม้ตัว Cell เองจะถูกประกาศเป็นค่าที่เปลี่ยนแปลงไม่ได้
use std::cell::Cell;
fn main() {
let my_num = Cell::new(10);
println!("Initial value: {}", my_num.get());
my_num.set(20);
println!("Updated value: {}", my_num.get());
let x = &my_num;
x.set(30); // Still works via immutable reference!
println!("Via immutable ref: {}", my_num.get());
}`RefCell<T>`: สำหรับชนิดข้อมูลที่คัดลอกไม่ได้
เมื่อคุณต้องการให้ชนิดข้อมูลที่ ไม่ได้ใช้งาน Copy ได้มีความสามารถในการเปลี่ยนแปลงค่าภายใน (เช่น String, Vec หรือโครงสร้างข้อมูลแบบกำหนดเอง) คุณจะใช้ RefCell<T>
RefCell ช่วยให้คุณรับ การอ้างอิงแบบเปลี่ยนแปลงได้ไปยังข้อมูลภายใน แต่จะบังคับใช้กฎการยืมของ Rust ขณะ ทำงาน ไม่ใช่ขณะคอมไพล์
การยืมขณะทำงานของ `RefCell`
RefCell มีเมธอดที่คืนค่าตัวชี้อัจฉริยะ:
borrow(): คืนค่าเป็นRef(ตัวชี้อัจฉริยะที่เปลี่ยนแปลงไม่ได้) คุณสามารถมีการยืมแบบเปลี่ยนแปลงไม่ได้หลายรายการพร้อมกันได้borrow_mut(): คืนค่าเป็นRefMut(ตัวชี้อัจฉริยะที่เปลี่ยนแปลงได้) คุณสามารถมีการยืมแบบเปลี่ยนแปลงได้เพียง หนึ่งรายการในแต่ละครั้ง
หากคุณละเมิดกฎเหล่านี้ขณะทำงาน โปรแกรมของคุณจะเกิด panic!
การใช้ `RefCell` (การยืมแบบเปลี่ยนแปลงไม่ได้)
ในที่นี้ เราใช้ borrow() เพื่อรับการอ้างอิงแบบเปลี่ยนแปลงไม่ได้ไปยัง String ภายใน RefCell จากนั้นเราสามารถพิมพ์เนื้อหาของมันได้
use std::cell::RefCell;
fn main() {
let my_string_cell = RefCell::new(String::from("Hello"));
let s1 = my_string_cell.borrow();
println!("Value: {}", *s1); // Dereference Ref to get String
let s2 = my_string_cell.borrow(); // Multiple immutable borrows are fine
println!("Another value: {}", *s2);
}การใช้ `RefCell` (การยืมแบบเปลี่ยนแปลงได้)
ตอนนี้เรามารับการอ้างอิงแบบเปลี่ยนแปลงได้โดยใช้ borrow_mut() ซึ่งทำให้เราแก้ไข String ได้ โปรดสังเกตว่าเมื่อ s_mut อยู่ในขอบเขตการใช้งานแล้ว จะไม่อนุญาตให้มีการยืมอื่นใด (ไม่ว่าจะเปลี่ยนแปลงได้หรือไม่ได้)
use std::cell::RefCell;
fn main() {
let my_string_cell = RefCell::new(String::from("World"));
{ // Scope for the mutable borrow
let mut s_mut = my_string_cell.borrow_mut();
s_mut.push_str(", Rust!");
}
// s_mut is out of scope here, so we can borrow again
let s_final = my_string_cell.borrow();
println!("Final value: {}", *s_final);
}การเกิดแพนิกขณะทำงานของ `RefCell`
หากคุณพยายามยืมแบบเปลี่ยนแปลงได้ขณะที่มีการยืมแบบเปลี่ยนแปลงได้อื่น (หรือการยืมแบบเปลี่ยนแปลงไม่ได้ใด ๆ) กำลังใช้งานอยู่ RefCell จะทำให้โปรแกรมของคุณเกิด panic! ขณะทำงาน ซึ่งช่วยป้องกันข้อมูลเสียหาย
ลองเรียกใช้โค้ดนี้เพื่อดูการทำงานจริง! โค้ดจะล้มเหลวพร้อมข้อผิดพลาดว่า "มีการยืมใช้งานอยู่แล้ว"
use std::cell::RefCell;
fn main() {
let my_value = RefCell::new(vec![1, 2, 3]);
let _first_mut_borrow = my_value.borrow_mut();
println!("First mutable borrow is active.");
// This line will cause a runtime panic!
// Try commenting it out to see the program run successfully.
let _second_mut_borrow = my_value.borrow_mut();
println!("This line will not be reached.");
}สรุป `Cell` เทียบกับ `RefCell`
การเลือกระหว่าง Cell กับ RefCell ขึ้นอยู่กับชนิดข้อมูลของคุณและวิธีที่คุณต้องการใช้งานข้อมูลนั้น:
Cell<T>: ใช้กับชนิดข้อมูลที่ใช้งานCopyได้ โดยจะแทนที่ค่าทั้งหมด และโดยทั่วไปเรียบง่ายกว่าและมีประสิทธิภาพสูงกว่าRefCell<T>: ใช้กับชนิดข้อมูลที่ใช้งานCopyไม่ได้ โดยมีการอ้างอิงไปยังข้อมูลภายในและบังคับใช้กฎการยืมขณะทำงาน ทำให้เปลี่ยนแปลงข้อมูลที่ซับซ้อนได้มากขึ้น
ตรวจสอบความเข้าใจ: Cell หรือ RefCell
คุณมี struct ที่ต้องเก็บตัวนับแบบเปลี่ยนแปลงได้ (u32) และรายการชื่อแบบเปลี่ยนแปลงได้ (Vec<String>) โดยทั้งสองอย่างต้องได้รับการอัปเดตผ่านการอ้างอิงแบบเปลี่ยนแปลงไม่ได้ไปยัง struct คุณจะใช้ชนิดข้อมูลที่รองรับการเปลี่ยนแปลงค่าภายในชนิดใดกับแต่ละฟิลด์
ทบทวน: การเปลี่ยนแปลงค่าภายใน
คุณได้เรียนรู้รูปแบบการเปลี่ยนแปลงค่าภายในของ Rust ซึ่งช่วยให้แก้ไขข้อมูลผ่านการอ้างอิงแบบเปลี่ยนแปลงไม่ได้ได้อย่างมีการควบคุมและปลอดภัย
Cell<T>: สำหรับชนิดข้อมูลCopyโดยจะแทนที่ค่าภายในRefCell<T>: สำหรับชนิดข้อมูลที่ไม่ใช่Copyโดยมีการอ้างอิงแบบเปลี่ยนแปลงได้หรือไม่ได้ที่ตรวจสอบขณะทำงาน- การละเมิดกฎของ
RefCellจะทำให้เกิดแพนิกขณะทำงาน เพื่อรับรองความปลอดภัย
ชนิดข้อมูลเหล่านี้มีความสำคัญต่อรูปแบบต่าง ๆ เช่น ออบเจ็กต์จำลอง การอ้างอิงแบบวนรอบ หรือกรณีที่การอ้างอิงแบบเปลี่ยนแปลงไม่ได้ที่ใช้ร่วมกันจำเป็นต้องติดตามสถานะภายใน
คำถามที่พบบ่อย
บทเรียน “การเปลี่ยนแปลงค่าภายใน: RefCell, Cell” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การเปลี่ยนแปลงค่าภายใน: RefCell, Cell” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Learn Rust Coding ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 3 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การเปลี่ยนแปลงค่าภายใน: RefCell, Cell”
เรียนรู้เกี่ยวกับ `RefCell` และ `Cell` สำหรับการเปลี่ยนแปลงค่าภายใน ทำให้เข้าถึงข้อมูลแบบเปลี่ยนแปลงค่าได้ผ่านการอ้างอิงแบบไม่เปลี่ยนแปลงค่าอย่างปลอดภัย คุณปฏิบัติ Learn Rust Coding ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Learn Rust Coding หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Learn Rust Coding บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน
บทเรียน “การเปลี่ยนแปลงค่าภายใน: RefCell, Cell” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Learn Rust Coding นี้ได้ไหม
ได้ บทเรียน Learn Rust Coding ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ตัวชี้อัจฉริยะ Box, Rc และ Arc
- การเปลี่ยนแปลงค่าภายใน: RefCell, Cell
- การทำงานพร้อมกันอย่างไร้กังวลด้วยเธรด