แบบฝึกหัด: บทที่ 14 - Smart Pointers
แบบฝึกหัดที่ 1: Box
ใช้ Box สร้าง recursive data structure (linked list)
ดูเฉลย
enum List {
Cons(i32, Box<List>),
Nil,
}
use List::{Cons, Nil};
fn main() {
let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
// Print list
fn print_list(list: &List) {
match list {
Cons(value, next) => {
print!("{} -> ", value);
print_list(next);
}
Nil => println!("Nil"),
}
}
print_list(&list); // 1 -> 2 -> 3 -> Nil
}
แบบฝึกหัดที่ 2: Rc
ใช้ Rc สร้าง shared ownership
ดูเฉลย
use std::rc::Rc;
fn main() {
let data = Rc::new(String::from("Hello"));
println!("Count after creation: {}", Rc::strong_count(&data));
{
let clone1 = Rc::clone(&data);
println!("Count after clone1: {}", Rc::strong_count(&data));
let clone2 = Rc::clone(&data);
println!("Count after clone2: {}", Rc::strong_count(&data));
}
println!("Count after block: {}", Rc::strong_count(&data));
}
Output:
Count after creation: 1
Count after clone1: 2
Count after clone2: 3
Count after block: 1
แบบฝึกหัดที่ 3: RefCell
ใช้ RefCell สำหรับ interior mutability
ดูเฉลย
use std::cell::RefCell;
fn main() {
let data = RefCell::new(5);
println!("Before: {:?}", data.borrow());
*data.borrow_mut() += 10;
println!("After: {:?}", data.borrow());
}
แบบฝึกหัดที่ 4: Rc + RefCell
รวม Rc และ RefCell เพื่อ shared mutable data
ดูเฉลย
use std::rc::Rc;
use std::cell::RefCell;
fn main() {
let data = Rc::new(RefCell::new(vec![1, 2, 3]));
let clone1 = Rc::clone(&data);
let clone2 = Rc::clone(&data);
// แก้ไขผ่าน clone1
clone1.borrow_mut().push(4);
// แก้ไขผ่าน clone2
clone2.borrow_mut().push(5);
// ดูผลลัพธ์
println!("{:?}", data.borrow()); // [1, 2, 3, 4, 5]
}
แบบฝึกหัดที่ 5: Weak
ใช้ Weak เพื่อป้องกัน reference cycle
ดูเฉลย
use std::rc::{Rc, Weak};
use std::cell::RefCell;
struct Node {
value: i32,
parent: RefCell<Weak<Node>>,
children: RefCell<Vec<Rc<Node>>>,
}
fn main() {
let leaf = Rc::new(Node {
value: 3,
parent: RefCell::new(Weak::new()),
children: RefCell::new(vec![]),
});
let branch = Rc::new(Node {
value: 5,
parent: RefCell::new(Weak::new()),
children: RefCell::new(vec![Rc::clone(&leaf)]),
});
// Set parent (weak reference)
*leaf.parent.borrow_mut() = Rc::downgrade(&branch);
println!("Leaf value: {}", leaf.value);
// Access parent through weak reference
if let Some(parent) = leaf.parent.borrow().upgrade() {
println!("Parent value: {}", parent.value);
}
}
👉 บทที่ 15