rust的生命周期问题理解(一)

复制代码
fn main() {
    let mut a = String::new();
    let mut b = &mut a;
    println!("{:?}",a);
    b.push('a');
}
复制代码
error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
  --> src/main.rs:9:21
   |
8  |     let mut b = &mut a;
   |                 ------ mutable borrow occurs here
9  |     println!("{:?}",a);
   |                     ^ immutable borrow occurs here
10 |     b.push('a');
   |     - mutable borrow later used here
   |
   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

原因是a和b变量都指向同一个内存区域

a和b都对应同一个区域有write的权限。

println!("{:?}",a);这句话将对a进行不可变的借用

问题出在了10行。此行b是对a的一个可变借用。

第9行是对a的不可变借用,第10行是对a的可变借用。两者矛盾。编译报错。

同理是:

复制代码
fn main() {

    //
    let rc = Rc::new(vec![1, 2, 3]);

    // 创建一个共享引用
    let  mut rc_clone = Rc::clone(&rc);

    // 此时的引用计数为2,`make_mut` 会在需要修改时进行克隆
    // let mut binding = rc.clone();
    let rc_mut = Rc::make_mut(&mut rc_clone);

    // 现在可以安全地修改 `rc_mut`,原始的 `rc` 和 `rc_clone` 不受影响
    rc_mut.push(4);
    // println!("rc length: {:?}", Rc::strong_count(&rc));
    println!("rc: {:?}", rc);           // [1, 2, 3]
    println!("rc_clone: {:?}", rc_clone); // [1, 2, 3]
    // println!("rc_mut: {:?}", rc_mut);    // [1, 2, 3, 4]
    rc_mut.push(4);
}

rc_mut是对rc_clone的可变借用。

println!("rc_clone: {:?}", rc_clone);变成了对rc_clone的不可变借用

两者矛盾了。因此报错。

但是这里面Rc::make_mut(&mut rc_clone);调用结束了后,为什么还认为存在对rc_clone的可变借用呢?原因见chatgpt回答:

一个更简单的类似的例子是这个:

复制代码
fn test(b :& String) {
    println!("{:?}",b)
}

fn test2(b :&mut String) -> &mut String{
    b.push('b');
    println!("{:?}",b);
    return b;
}

fn main() {
    let mut a = String::new();
    let c = test2(&mut a);
    test(&a);
    a.push('a');
    c.push('b');
}

cannot borrow a as immutable because it is also borrowed as mutable 是什么错误,详细解释下

相关推荐
华仔啊2 小时前
为啥不用 MP 的 saveOrUpdateBatch?MySQL 一条 SQL 批量增改才是最优解
java·后端
武子康3 小时前
大数据-242 离线数仓 - DataX 实战:MySQL 全量/增量导入 HDFS + Hive 分区(离线数仓 ODS
大数据·后端·apache hive
砍材农夫3 小时前
TCP和UDP区别
后端
千寻girling4 小时前
一份不可多得的 《 Django 》 零基础入门教程
后端·python·面试
千寻girling4 小时前
Python 是用来做 AI 人工智能 的 , 不适合开发 Web 网站 | 《Web框架》
人工智能·后端·算法
贾铭4 小时前
如何实现一个网页版的剪映(三)使用fabric.js绘制时间轴
前端·后端
xiaoye20184 小时前
Spring 自定义 Redis 超时:TTL、TTI 与 Pipeline 实战
后端
程序员爱钓鱼7 小时前
GoHTML解析利器:github.com/PuerkitoBio/goquery实战指南
后端·google·go
golang学习记7 小时前
从“大泥球“到模块化单体:Spring Modulith + IntelliJ IDEA 拯救你的代码
后端·intellij idea
颜酱7 小时前
一步步实现字符串计算器:从「转整数」到「带括号与优化」
javascript·后端·算法