V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
echotpq
V2EX  ›  问与答

rust 小白,求教所有权报错

  •  
  •   echotpq · 2021-09-09 14:26:41 +08:00 · 1070 次点击
    这是一个创建于 1153 天前的主题,其中的信息可能已经有所发展或是发生改变。

    rust 小白,求教

    1 、合法不会报错 fn main() {

    let mut s = String::from("hello");

    let r1 = &mut s;

    let r2 = r1;

    println!("{}",r2);

    println!("{}",s);

    }

    2 、报错,提示 mutable & immutable 错误

    fn main() {

    let mut s = String::from("hello");

    let r1 = &mut s;

    let r2 = r1;

    println!("{}",s);

    println!("{}",r2);

    }

    两者有什么区别,请高手指教一下

    5 条回复    2021-09-09 17:10:05 +08:00
    misdake
        1
    misdake  
       2021-09-09 14:57:29 +08:00
    1 里面,r2 在 println 之后就还回去了,所以 s 可以接着用
    2 里面,打印 s 的时候,r2 还借着 s 的 mut 引用,所以不能访问 s
    echotpq
        2
    echotpq  
    OP
       2021-09-09 15:23:14 +08:00
    可是 1 里面 r2 在 println 一次之后,还能继续 println 一次 ,比如 println!("{}",r2); println!("{}",r2); println!("{}",s);
    不是 println 一次之后就还回去了吗?怎么还能继续 println 呢?@misdake
    XiaoxiaoPu
        3
    XiaoxiaoPu  
       2021-09-09 15:43:47 +08:00   ❤️ 1
    kaisery.github.io/trpl-zh-cn/ch04-02-references-and-borrowing.html
    注意一个引用的作用域从声明的地方开始一直持续到最后一次使用为止。

    1 里面,r2 的最后一次使用在第 5 行,后面就不在 r2 的作用域了
    2 里面,r2 的最后一次使用在第 6 行,第 5 行的时候 r2 还是有效的
    echotpq
        4
    echotpq  
    OP
       2021-09-09 15:51:38 +08:00
    @XiaoxiaoPu 谢谢,明白了
    ke1e
        5
    ke1e  
       2021-09-09 17:10:05 +08:00
    个人理解:

    首先,引用是否有效,取决于它引用的对象是否有效;

    在 1 中:r2 是 s 的可变引用,s 在 println!("{}",s); 后被清除失效,所以'a (从 s 被定义到 println 之间)都是存活有效的,rust 的引用检查器自然会认为在'a 中,r2 的引用是有效的。这样你在'a 中调用 println!("{}",r2);都是合法的;

    在 2 中:同样道理,println!("{}",r2); 在 'a 之外被调用,此时 s 已经被清除,它的引用也都是失效的,所以不合法
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1008 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 21:05 · PVG 05:05 · LAX 13:05 · JFK 16:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.