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 是否于内存中复制过?
1
sunjiayao 320 天前 1
s1 的所有权给 s2 了
|
2
sleeepyy 320 天前 1
没有销毁,return 的时候把所有权给 s2 了
|
3
yelog 320 天前 1
上面两位老哥说的很好, 我补充一下官网原文关于这块的描述和示例, 可以尝试理解一下
https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html#return-values-and-scope |
4
ch3nOr 320 天前 1
修改了一下楼主的程序,打印了一下内存地址,发现在 test 内 move 内存地址也会发生改变,move 到外部也会
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=fcfb04f8f33db75f1934513021102b30 |
5
dxatgp02 OP |
6
detached 320 天前 2
@ch3nOr 这个是符合预期的,"test1"这个字符串所在的内存并没有发生变化。而每一个 variable(s1,s2,s3)都是一个新的,他们均指向这个字符串。
|
7
ch3nOr 320 天前 2
@detached
验证了一下,确实是这样的: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8e72d327ee3e3379797b5b156f034ad3 上面 #4 的程序打印的是 s1 、s2 、s3 的地址 |
8
docxs 320 天前 via iPhone 1
你对比理解成 cpp 的 move ,就好理解了
|
9
araraloren 318 天前 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. |
10
buxudashi 314 天前 1
你认为的消毁是什么?
把全部内存段内的位变成 0 ? 事实上的销毁是。你不管里面的数据是什么。你不取值不引用它的索引就算销了。 |
11
Terry166 246 天前
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 │ │ │ // 保存在堆上的数据 +–––+–––+–––+–––+–––+–––+–––+–––+– |