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 是什么错误,详细解释下

相关推荐
星空下夜猫子8 分钟前
JAVA 使用POI实现单元格行合并生成
java·开发语言
liangshanbo121520 分钟前
JavaScript 中的一些常见陷阱
开发语言·javascript·ecmascript
VaporGas1 小时前
掌握Java封装:以猜拳小游戏为例,深入理解OOP
java·开发语言·学习·面向对象编程·oop·猜拳游戏·封装思想
Bitup_bitwin1 小时前
C++中的for-each循环
开发语言·c++
martian6651 小时前
学懂C++(五十四):掌握 C++11 标准:提升开发效率与安全性的关键
开发语言·c++
小tenten1 小时前
js延迟for内部循环方法
开发语言·前端·javascript
程序员大金1 小时前
基于SpringBoot+Vue+MySQL的垃圾分类回收管理系统
java·vue.js·spring boot·后端·mysql·mybatis
CJH~2 小时前
Java入门:09.Java中三大特性(封装、继承、多态)01
java·开发语言·单例模式
我的运维人生2 小时前
JavaScript在网页设计中的应用案例
开发语言·javascript·ecmascript·运维开发·技术共享
coding侠客2 小时前
Spring Boot 注解探秘:常用配置值读取注解的魔力
java·spring boot·后端·spring·spring cloud