目录智能指针Box堆对象分配Deref解引用Drop释放资源Rc与Arc实现1vN所有权机制Cell与RefCell内部可变性模式和匹配智能指针Box堆对象分配什么是Box?Box是一个智能指针,它在堆上分配对象。Box自动管理内存,当不再需要时会自动释
什么是 Box?
fn main() {
// 在堆上分配一个整数
let boxed_num = Box::new(42);
println!("Boxed number: {}", boxed_num); // 输出: Boxed number: 42
// 解引用
let num = *boxed_num;
println!("Unboxed number: {}", num); // 输出: Unboxed number: 42
}
什么是 Deref 特征?
use std::ops::Deref;
struct MyBox<T>(T);
impl<T> Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn main() {
let my_box = MyBox(42);
println!("MyBox value: {}", *my_box); // 输出: MyBox value: 42
}
什么是 Drop 特征?
struct MyResource {
name: String,
}
impl Drop for MyResource {
fn drop(&mut self) {
println!("Dropping resource: {}", self.name);
}
}
fn main() {
{
let res = MyResource { name: String::from("Resource A") };
println!("Resource created: {}", res.name); // 输出: Resource created: Resource A
} // 在这里,资源会被自动释放
println!("After resource dropped"); // 输出: After resource dropped
}
什么是 Rc?
use std::rc::Rc;
fn main() {
let a = Rc::new(String::from("Hello"));
println!("Count after creating a: {}", Rc::strong_count(&a)); // 输出: Count after creating a: 1
let b = a.clone();
println!("Count after cloning a into b: {}", Rc::strong_count(&a)); // 输出: Count after cloning a into b: 2
{
let c = a.clone();
println!("Count after cloning a into c: {}", Rc::strong_count(&a)); // 输出: Count after cloning a into c: 3
} // 在这里,c 被释放,引用计数减 1
println!("Count after c goes out of scope: {}", Rc::strong_count(&a)); // 输出: Count after c goes out of scope: 2
}
什么是 Arc?
use std::sync::Arc;
fn main() {
let a = Arc::new(String::from("Hello"));
println!("Count after creating a: {}", Arc::strong_count(&a)); // 输出: Count after creating a: 1
let b = a.clone();
println!("Count after cloning a into b: {}", Arc::strong_count(&a)); // 输出: Count after cloning a into b: 2
{
let c = a.clone();
println!("Count after cloning a into c: {}", Arc::strong_count(&a)); // 输出: Count after cloning a into c: 3
} // 在这里,c 被释放,引用计数减 1
println!("Count after c goes out of scope: {}", Arc::strong_count(&a)); // 输出: Count after c goes out of scope: 2
}
什么是 Cell?
use std::cell::Cell;
fn main() {
let mut cell = Cell::new(0);
println!("Initial value: {}", cell.get()); // 输出: Initial value: 0
cell.set(42);
println!("New value: {}", cell.get()); // 输出: New value: 42
}
什么是 RefCell?
use std::cell::RefCell;
fn main() {
let mut refcell = RefCell::new(0);
println!("Initial value: {}", *refcell.borrow()); // 输出: Initial value: 0
*refcell.borrow_mut() = 42;
println!("New value: {}", *refcell.borrow()); // 输出: New value: 42
}
use std::cell::RefCell;
fn main() {
let refcell = RefCell::new(0);
{
let borrowed = refcell.borrow();
println!("Borrowed value: {}", *borrowed); // 输出: Borrowed value: 0
// 无法同时借用不可变引用和可变引用
// let borrowed_mut = refcell.borrow_mut(); // 错误
}
{
let borrowed_mut = refcell.borrow_mut();
*borrowed_mut = 42;
println!("Mutated value: {}", *borrowed_mut); // 输出: Mutated value: 42
}
}
多层借用示例
use std::cell::RefCell;
fn main() {
let outer_refcell = RefCell::new(0);
let inner_refcell = RefCell::new(outer_refcell);
{
let outer_borrowed = inner_refcell.borrow();
println!("Outer borrowed value: {}", *outer_borrowed.borrow()); // 输出: Outer borrowed value: 0
*outer_borrowed.borrow_mut() = 42;
println!("Outer mutated value: {}", *outer_borrowed.borrow()); // 输出: Outer mutated value: 42
}
{
let inner_borrowed = inner_refcell.borrow();
println!("Inner borrowed value: {}", *inner_borrowed.borrow()); // 输出: Inner borrowed value: 42
}
}
多线程示例
RefCell
适用于单线程场景。Arc<Mutex>
。use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let shared_data = Arc::new(Mutex::new(0));
let thread1_data = Arc::clone(&shared_data);
let thread2_data = Arc::clone(&shared_data);
let handle1 = thread::spawn(move || {
let mut data = thread1_data.lock().unwrap();
*data += 1;
println!("Thread 1 value: {}", *data); // 输出: Thread 1 value: 1
});
let handle2 = thread::spawn(move || {
let mut data = thread2_data.lock().unwrap();
*data += 2;
println!("Thread 2 value: {}", *data); // 输出: Thread 2 value: 3
});
handle1.join().unwrap();
handle2.join().unwrap();
println!("Final value: {}", *shared_data.lock().unwrap()); // 输出: Final value: 3
}
组合使用示例
Box
可以与其他智能指针结合使用,实现更复杂的功能。
示例:Box<Rc<String>>
use std::rc::Rc;
fn main() {
let boxed_string = Box::new(Rc::new(String::from("Hello")));
println!("Boxed string: {}", *boxed_string); // 输出: Boxed string: Hello
let cloned_string = boxed_string.clone();
println!("Cloned string: {}", *cloned_string); // 输出: Cloned string: Hello
}
组合使用示例
Box
与 Rc
结合使用可以实现堆上的共享所有权。
示例:Box<Rc<String>>
use std::rc::Rc;
fn main() {
let boxed_string = Box::new(Rc::new(String::from("Hello")));
println!("Boxed string: {}", *boxed_string); // 输出: Boxed string: Hello
let cloned_string = Box::new(Rc::clone(&*boxed_string));
println!("Cloned string: {}", *cloned_string); // 输出: Cloned string: Hello
}
Box
与 Arc
结合使用可以实现多线程下的共享所有权。
示例:Box<Arc<String>>
use std::sync::Arc;
fn main() {
let boxed_string = Box::new(Arc::new(String::from("Hello")));
println!("Boxed string: {}", *boxed_string); // 输出: Boxed string: Hello
let cloned_string = Box::new(Arc::clone(&*boxed_string));
println!("Cloned string: {}", *cloned_string); // 输出: Cloned string: Hello
}
Box
与 RefCell
结合使用可以实现堆上的内部可变性。
示例:Box<RefCell<String>>
use std::cell::RefCell;
fn main() {
let boxed_string = Box::new(RefCell::new(String::from("Hello")));
println!("Boxed string: {}", *boxed_string.borrow()); // 输出: Boxed string: Hello
*boxed_string.borrow_mut() = String::from("World");
println!("Updated string: {}", *boxed_string.borrow()); // 输出: Updated string: World
}
Box
与 Cell
结合使用可以实现堆上的内部可变性。
示例:Box<Cell<String>>
use std::cell::Cell;
fn main() {
let boxed_string = Box::new(Cell::new(String::from("Hello")));
println!("Boxed string: {}", boxed_string.get()); // 输出: Boxed string: Hello
boxed_string.set(String::from("World"));
println!("Updated string: {}", boxed_string.get()); // 输出: Updated string: World
}
什么是模式匹配?
示例:基本的模式匹配
fn main() {
let point = (3, 4);
// 分解元组
let (x, y) = point;
println!("x: {}, y: {}", x, y); // 输出: x: 3, y: 4
// 匹配枚举
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
let msg = Message::Write(String::from("hello"));
match msg {
Message::Quit => println!("Quit"),
Message::Move { x, y } => println!("Move to ({}, {})", x, y),
Message::Write(text) => println!("Write: {}", text),
Message::ChangeColor(r, g, b) => println!("Change color to ({}, {}, {})", r, g, b),
}
}
元组模式用于分解元组类型的值。
fn main() {
let point = (3, 4);
// 分解元组
let (x, y) = point;
println!("x: {}, y: {}", x, y); // 输出: x: 3, y: 4
// 使用 `_` 忽略某些元素
let (x, _) = point;
println!("x: {}", x); // 输出: x: 3
}
枚举模式用于匹配枚举类型的值。
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let msg = Message::Write(String::from("hello"));
match msg {
Message::Quit => println!("Quit"),
Message::Move { x, y } => println!("Move to ({}, {})", x, y),
Message::Write(text) => println!("Write: {}", text),
Message::ChangeColor(r, g, b) => println!("Change color to ({}, {}, {})", r, g, b),
}
}
结构体模式用于分解结构体类型的值。
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 3, y: 4 };
// 分解结构体
let Point { x, y } = point;
println!("x: {}, y: {}", x, y); // 输出: x: 3, y: 4
// 使用 `_` 忽略某些字段
let Point { x, .. } = point;
println!("x: {}", x); // 输出: x: 3
}
条件模式允许在模式匹配中添加额外的条件。
fn main() {
let point = (3, 4);
match point {
(x, y) if x == y => println!("x and y are equal"),
(x, y) if x > y => println!("x is greater than y"),
(x, y) => println!("x: {}, y: {}", x, y),
}
}
无约束模式用于匹配任何值。
fn main() {
let point = (3, 4);
match point {
(x, y) @ _ => println!("x: {}, y: {}", x, y), // `@` 用于保留整个模式
}
}
列表模式用于匹配列表类型的值。
fn main() {
let list = vec![1, 2, 3];
match list.as_slice() {
[first, second, third] => println!("First: {}, Second: {}, Third: {}", first, second, third),
[first, .., last] => println!("First: {}, Last: {}", first, last),
_ => println!("Unknown list"),
}
}
字段模式用于匹配结构体或枚举类型的特定字段。
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 3, y: 4 };
match point {
Point { x, .. } => println!("x: {}", x), // 使用 `..` 忽略其他字段
}
}
枚举模式可以结合字段模式使用。
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
fn main() {
let msg = Message::Move { x: 3, y: 4 };
match msg {
Message::Move { x, .. } => println!("x: {}", x), // 使用 `..` 忽略其他字段
_ => println!("Other message"),
}
}
函数参数也可以使用模式匹配。
fn print_point((x, y): (i32, i32)) {
println!("Point: ({}, {})", x, y);
}
fn main() {
let point = (3, 4);
print_point(point);
}
循环也可以使用模式匹配。
fn main() {
let list = vec![1, 2, 3, 4];
for (index, value) in list.iter().enumerate() {
println!("Index: {}, Value: {}", index, value);
}
}
模式守卫允许在模式匹配中添加额外的条件。
fn main() {
let point = (3, 4);
match point {
(x, y) if x == y => println!("x and y are equal"),
(x, y) if x > y => println!("x is greater than y"),
(x, y) => println!("x: {}, y: {}", x, y),
}
}
模式匹配可以添加类型约束。
fn main() {
let point = (3, 4);
match point {
(x, y) if x.is_positive() && y.is_positive() => println!("Both positive"),
(x, y) => println!("x: {}, y: {}", x, y),
}
}
trait Positive {
fn is_positive(&self) -> bool;
}
impl Positive for i32 {
fn is_positive(&self) -> bool {
*self > 0
}
}
模式匹配可以有多个分支。
fn main() {
let point = (3, 4);
match point {
(0, 0) => println!("Origin"),
(x, 0) | (0, y) => println!("On an axis"),
(x, y) => println!("General point: ({}, {})", x, y),
}
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!