Rust所有权和借用规则示例
众所周知,所有权是Rust区别于其他语言的一大特色,只要代码满足了所有权规则,我们就不用担心内存的泄露的问题。
让代码在编译阶段就解决内存的问题,而不是在运行崩溃后再调试。
Rust中,所有权和借用的规则其实并不复杂,所有权有3条规则,借用只有2条规则。
所有权的规则
1. Rust中的每一个值都有一个对应的变量作为它的所有者
这个规则很好理解,比如下面的2个值 5
和 hello
分别属于变量 x
和 y
fn main() {
let x = 5;
let y = String::from("hello");
println!("x = {}, and y = {}", x, y);
}
2. 在同一时间内,值有且仅有一个所有者
比如下面的示例,当 x
的值给了 y
之后,x
就不能再用了,值hello
只能有一个所有者。
fn main() {
let x = String::from("hello");
let y = x;
println!("x = {}, y = {}", x, y); // 这里会报错
}
3. 当所有者离开自己的作用域时,它持有的值就会被释放掉
fn main() {
let x = String::from("hello");
{
let y = String::from("world");
println!("{} {}", x, y);
}
println!("{} {}", x, y); // 这里会报错,获取不到 y,y已经释放了。
}
借用(引用)的规则
Rust中,引用和借用是一个意思,用借用能更准确的表达变量传递的含义。
1. 在任何一段给定的时间里,你要么只能拥有一个可变引用,要么只能拥有任意数量的不可变引用
y
和z
都拥有x
的不可变借用。
fn main() {
let x = 5;
let y = &x;
let z = &x;
println!("y = {}, z = {}", y, z);
}
如果 y
拥有可变借用,而 z
拥有不可变借用,是不行的。
fn main() {
let mut x = 5;
let y = &mut x;
let z = &x; // 这里会报错,因为同一段时间内,既有x的不可变借用,又有可变借用
println!("y = {}, z = {}", y, z);
}
2. 借用总是有效的
只要借用能编译,就说明借用是有效的,编译器会帮助我们确保借用都是有效的。
fn main() {
let x = vec![1, 2, 3];
lost(x);
let y = &x; // 这里编译会报错,因为 x 已经转移到 lost 函数中,在 main 中失效了
println!("y = {:?}", y);
}
fn lost(x: Vec<i32>) {
println!("lost: {:?}", x);
}
下面这样借用就不会报错,因为x
只是借用给 no_lost
函数。
fn main() {
let x = vec![1, 2, 3];
not_lost(&x);
let y = &x;
println!("y = {:?}", y);
}
fn not_lost(x: &Vec<i32>) {
println!("lost: {:?}", x);
}
总结
所有权和借用是Rust确保内存安全使用的重要手段,上面的示例用最简单的方式展示了这些规则。
实际项目中,刚开始其实很难保证所有权和借用的规则,会经常遇到编译不了的情况。
但是,一旦养成了习惯,写代码时,脑中自然浮现变量在内存中的情况,自然就写出了内存安全的代码。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 易语言 —— 开山篇
2014-06-29 Linux 小知识翻译 - 「DNS服务器」
2011-06-29 《CLR Via C# 第3版》笔记之(七) - const和readonly