[Rust] Borrow checker
Three rules:
- There can only be one value owner
- There can be unlimited immutable borrows (reference) with no mutable references
- There can be only one mutable reference and no immuntable references
There is one rule for lifetimes
- A reference cannnot outlive its value
Example
#[derive(Debug)]
struct MyStruct {
age: usize
}
fn main() {
let mut items: Vec<&MyStruct> = vec![];
{
let item = MyStruct {age: 0};
items.push(&item); // item does not live long enough borrowed ..
}
println!("{:?}", items); // borrow later used here
}
Stated differently
- One var owns the data
- One var can change the data
- Many vars can look at the data
- You cannot look and change the data simultaneously
- You cannot refer to something that has been dropped (released in memory)
Example:
#[derive(Debug)]
struct Item {
count: usize
}
fn add_one(mut item: Item) {
item.count += 1;
}
fn main() {
let item = Item {count: 1};
println!("{:?}", item);
add_one(item);
println!("{:?}", item);
}
// let item = Item {count: 1}; this line owns the item
// add_one(items); move the ownership to add_one function
// println!("{:?}", item); this line will cause error because item is moved to add_one function
Next step:
fn add_one(item: &Item) {
item.count += 1;
}
// item.count += 1; not mutable
fn main() {
let item = Item {count: 1};
println!("{:?}", item);
add_one(&item);
println!("{:?}", item);
}
Now we pass the reference. But now get not mutable error
Next step:
fn add_one(item: &mut Item) {
item.count += 1;
}
fn main() {
let item = Item {count: 1};
println!("{:?}", item);
add_one(&item); // error, consider mutably borrowing here: `&mut item`
println!("{:?}", item);
}
Next step:
fn add_one(item: &mut Item) {
item.count += 1;
}
fn main() {
let item = Item {count: 1};
println!("{:?}", item);
add_one(&mut item); // error: cannot borrow `item` as mutable, as it is not declared as mutable
println!("{:?}", item);
}
Next step:
fn add_one(item: &mut Item) {
item.count += 1;
}
fn main() {
let mut item = Item {count: 1};
println!("{:?}", item);
add_one(&mut item);
println!("{:?}", item);
}
Practic
- Create a function called print_all that takes in an immutable borrow (reference) to items and prints each item, one at a time;
in main function
- create a vector of Items call items
- grab a mutable reference to item 0 (get_mut)
- print item 0
- call print_all
- print item 0 (you have to code this all)
fn print_all(items: &Vec<Item>){
for item in items {
println!("{:?}", item);
}
}
fn main() {
let mut items = vec![Item {count: 1}];
let mut first = items.first_mut();
println!("{:?}", first);
print_all(&items);
// println!("{:?}", first); // you cannot do it here because first is already moved to print_all function
}
- get a mutable reference named one, get_mut(0)
- get mutable reference named two, get_mut(1)
- println!(?{:?}", one)
fn main() {
let mut items = vec![Item {count: 1}];
let first = items.get_mut(0);
let second = items.get_mut(1); // you cannot hold two mutable references at the same time
}
fn main() {
let items = vec![1,2,3] // vec![1,2,3] temporary value ends here
.iter()
.map(|x| x + 1);
println!("{:?}", items);
}
Fix:
fn main() {
let data = vec![1,2,3]
let items = data
.iter()
.map(|x| x + 1);
println!("{:?}", items);
}
分类:
Rust
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2022-05-29 [Kubernates] Kubernetes Intro on Google cloud
2017-05-29 [RxJS] Replace zip with combineLatest when combining sources of data
2017-05-29 [RxJS] Use takeUntil instead of manually unsubscribing from Observables