Rust引用与切片
学习如何在Rust中使用不可变与可变引用借用数据,理解借用规则(Aliasing XOR Mutability),以及切片的使用方法。
这是Rust基础系列的第6篇文章。所有权保证了内存安全,但如果频繁转移所有权会使代码变得繁琐。“借用”(Borrowing)允许在不获取所有权的情况下访问数据。
使用引用进行借用#
引用允许你指向某个值而不获取其所有权。使用 & 运算符创建引用:
fn calculate_length(s: &String) -> usize {
s.len()
}
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1);
println!("'{s1}' 的长度是 {len}。");
}rust由于 calculate_length 接受 &String 引用,s1 被借用而不是被移动。函数调用后 s1 依然有效。
可变引用#
默认情况下,引用是不可变的。要修改借用的数据,需使用可变引用 &mut:
fn change(s: &mut String) {
s.push_str(", world");
}
fn main() {
let mut s = String::from("hello");
change(&mut s);
println!("{s}");
}rust创建可变引用前,原变量必须也使用 mut 声明。
借用的核心规则#
Rust在编译期严格执行以下规则以防止数据竞争:
在同一时间内,你要么拥有任意多个不可变引用 (
&T),要么拥有唯一个可变引用 (&mut T),但不能两者兼有。
let mut s = String::from("hello");
let r1 = &s; // OK
let r2 = &s; // OK
// let r3 = &mut s; // 错误:已存在不可变引用,无法再借用为可变引用
println!("{r1} 与 {r2}");rust这种“别名与可变性互斥”的规则保证了在程序其他部分读取数据时,数据绝不会被意外修改。
切片#
切片是对集合中一段连续元素序列的引用,而不是对整个集合的引用。
字符串切片#
字符串切片 (&str) 引用 String 的一部分:
let s = String::from("hello world");
let hello: &str = &s[0..5];
let world: &str = &s[6..11];rust字符串字面值 ("hello") 本质上就是指向已编译二进制数据的字符串切片。
数组切片#
切片同样适用于数组与向量:
let a = [1, 2, 3, 4, 5];
let slice: &[i32] = &a[1..3];
assert_eq!(slice, &[2, 3]);rust总结#
通过引用(& 和 &mut)借用数据可以安全地共享数据。切片(&str 和 &[T])提供了对序列的灵活只读视图。本系列的下一篇文章将探讨“结构体”(Struct)。