引用与解引用
- 引用是指向内存地址的指针类型。
- 使用 & 符号创建引用,并用 * 进行解引用。
引用与解引用示例
fn main() {
let x = 5;
let y = &x;
assert_eq!(5, x);
assert_eq!(5, *y);
}
不可变引用
不可变引用示例
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1);
println!("The length of '{}' is {}.", s1, len);
}
fn calculate_length(s: &String) -> usize {
s.len()
}
可变引用
- 可变引用允许修改引用的数据。
- 同一作用域内,对特定数据只能存在一个可变引用。
可变引用示例
fn main() {
let mut s = String::from("hello");
change(&mut s);
println!("{}", s);
}
fn change(some_string: &mut String) {
some_string.push_str(", world");
}
可变引用限制
- 可变引用与不可变引用不能同时存在。
- 可变引用在同一作用域内只能有一个。
可变引用错误示例
fn main() {
let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &s;
println!("{} and {}", r1, r2);
}
NLL(Non-Lexical Lifetimes)
- Rust 编译器优化,允许在作用域结束前不再使用的引用结束。
- 有助于解决引用作用域与变量作用域不一致的问题。
悬垂引用(Dangling References)
- 悬垂引用指向的内存可能不存在或已被其他变量使用。
- Rust 编译器确保引用永远不会是悬垂状态。
悬垂引用示例
fn main() {
let reference_to_nothing = dangle();
}
fn dangle() -> &String {
let s = String::from("hello");
&s
}
fn no_dangle() -> String {
let s = String::from("hello");
s
}
借用规则总结
- 同一时刻,只能有一个可变引用或多个不可变引用。
- 引用必须总是有效的。
总结
- 引用与借用是 Rust 中管理内存的重要概念。
- 不可变引用允许共享但不允许修改。
- 可变引用允许修改但同一时间只能有一个。
- NLL 优化了引用作用域,使其更加安全和灵活。
- Rust 编译器防止悬垂引用,确保内存安全。