萌新 rust 一个关于作用域的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dxatgp02
V2EX    Rust

萌新 rust 一个关于作用域的问题

  •  
  •   dxatgp02 2024-01-15 14:29:40 +08:00 2053 次点击
    这是一个创建于 633 天前的主题,其中的信息可能已经有所发展或是发生改变。
    fn main(){ let s2 = test(); println!("s2={}",s2 ); } fn test() -> String{ let s1 = String::from("test1"); return s1 } 

    打印出 s2=test1

    这里有一个疑问,s1 对应的内存有没有被销毁? return s1 这时作用域已完成,不是因销毁 s1 吗,那返回到 main 里的是什么? “test1"这 string 是否于内存中复制过?

    11 条回复    2024-03-29 18:43:33 +08:00
    luman
        1
    luman  
       2024-01-15 14:38:37 +08:00   1
    s1 的所有权给 s2 了
    sleeepyy
        2
    sleeepyy  
       2024-01-15 14:46:14 +08:00   1
    没有销毁,return 的时候把所有权给 s2 了
    yelog
        3
    yelog  
       2024-01-15 14:55:58 +08:00   1
    上面两位老哥说的很好, 我补充一下官网原文关于这块的描述和示例, 可以尝试理解一下

    https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html#return-values-and-scope
    ch3nOr
        4
    ch3nOr  
       2024-01-15 15:11:07 +08:00   1
    修改了一下楼主的程序,打印了一下内存地址,发现在 test 内 move 内存地址也会发生改变,move 到外部也会

    https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=fcfb04f8f33db75f1934513021102b30
    dxatgp02
        5
    dxatgp02  
    OP
       2024-01-15 16:31:27 +08:00
    感谢各位大佬的指点自己的理解力有限,感觉被绕进去了。
    detached
      &nbs; 6
    detached  
       2024-01-15 16:32:54 +08:00   2
    @ch3nOr 这个是符合预期的,"test1"这个字符串所在的内存并没有发生变化。而每一个 variable(s1,s2,s3)都是一个新的,他们均指向这个字符串。
    ch3nOr
        7
    ch3nOr  
       2024-01-15 17:09:11 +08:00   2
    @detached

    验证了一下,确实是这样的:

    https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8e72d327ee3e3379797b5b156f034ad3


    上面 #4 的程序打印的是 s1 、s2 、s3 的地址
    docxs
        8
    docxs  
       2024-01-15 17:26:37 +08:00 via iPhone   1
    你对比理解成 cpp 的 move ,就好理解了
    araraloren
        9
    araraloren  
       2024-01-17 10:03:21 +08:00   1
    It transfer the ownership of s1 to s2(move is bitwise copy, but not call the drop of `s1`).
    And `s2` will be dropped when out of scope of main.
    buxudashi
        10
    buxudashi  
       2024-01-21 15:15:38 +08:00   1
    你认为的消毁是什么?

    把全部内存段内的位变成 0 ?

    事实上的销毁是。你不管里面的数据是什么。你不取值不引用它的索引就算销了。
    Terry166
        11
    Terry166  
       2024-03-29 18:43:33 +08:00
    String 是一个可变的,堆上分配的 UTF-8 的字节缓冲区,它是可增长的、可变的、有所有权的、UTF-8 编码的字符串类型,使用 to_string 或者 String::from 创建。

    fn test() -> String{
    let s1 = String::from("test1");
    return s1
    } // 创建并返回一个具有所有权的字符串,

    let s2 = test(); // 把所有权转移给 s2 ,s1 就失效了。

    内存表示如下:
    [ s1 ] [s2 ] // 栈上的胖指针(包含三个字:地址,容量,大小)
    +++++++
    stack frame │ │ │ │ │ 8 │ 5 │
    ++++ │+++│
    │ │
    ++

    +V++++++++
    heap │ t │ e │ s │ t │ 1 │ l │ │ │ // 保存在堆上的数据
    +++++++++
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     891 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 41ms UTC 20:00 PVG 04:00 LAX 13:00 JFK 16:00
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86