- 借用(Borrowing):
- Rust通过借用机制允许在不转移所有权的情况下使用数据。借用分为可变借用(
&mut
)和不可变借用(&
)。不可变借用允许多个变量同时借用数据,可变借用则只允许一个变量借用数据,以防止数据竞争。
- 示例:
fn main() {
let s = String::from("hello");
let len1 = calculate_length(&s);
let len2 = calculate_length(&s);
println!("Lengths: {}, {}", len1, len2);
}
fn calculate_length(s: &str) -> usize {
s.len()
}
- 在这个例子中,
&s
创建了对s
的不可变借用,函数calculate_length
通过不可变借用s
来计算字符串长度。多个不可变借用可以同时存在。
- 生命周期标注(Lifetime Annotations):
- 当函数参数和返回值的生命周期关系不明确时,需要显式标注生命周期。生命周期参数用单引号(
'
)开头,后跟一个名称。
- 示例:
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
- 在
longest
函数中,'a
生命周期参数标注了x
、y
参数以及返回值的生命周期,表明它们都具有相同的生命周期。这确保了返回的字符串切片在调用者的作用域内是有效的。
- 引用计数智能指针(
Rc
):
Rc
(std::rc::Rc
)是用于堆上数据的引用计数智能指针,允许多个所有者共享相同的数据。Rc
会记录有多少个变量引用了堆上的数据,当引用计数为0时,数据会被自动释放。
- 示例:
use std::rc::Rc;
fn main() {
let s1 = Rc::new(String::from("shared string"));
let s2 = s1.clone();
let s3 = s1.clone();
println!("Rc count: {}", Rc::strong_count(&s1));
}
- 在这个例子中,
s1
创建了一个Rc
包裹的字符串,s2
和s3
通过clone
方法增加了引用计数。Rc::strong_count
可以获取当前的引用计数。
- 互斥锁(
Mutex
):
Mutex
(std::sync::Mutex
)用于线程安全地访问数据。它提供了一种机制,使得同一时间只有一个线程可以访问被它保护的数据。多个线程可以通过获取Mutex
的锁来访问数据,从而确保数据一致性。
- 示例:
use std::sync::{Mutex, Arc};
use std::thread;
fn main() {
let data = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let data = Arc::clone(&data);
let handle = thread::spawn(move || {
let mut num = data.lock().unwrap();
*num += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Final value: {}", *data.lock().unwrap());
}
- 在这个例子中,
Mutex
保护了一个整数变量,多个线程通过获取Mutex
的锁来修改这个变量,从而保证数据一致性。Arc
用于在多个线程间共享Mutex
。