rust - 移动后参考与参考前不同
问题描述
以下内容写在 Rust 文档中:
let s1 = String::from("hello"); let s2 = s1;
当我们将 s1 分配给 s2 时,会复制 String 数据,这意味着我们会复制堆栈上的指针、长度和容量。我们不会复制指针所指堆上的数据。
当我运行以下代码时,
let s1 = String::from("aa");
let p2 = &s1;
println!("p2:{:p}", p2);
let s2 = s1;
let p3 = &s2;
println!("p3:{:p}", p3);
输出:
p2:0x7ffc1bd2e730
p3:0x7ffc1bd2e7a0
为什么p2指向的地址和p3指向的地址不一样?
解决方案
s1
是一个struct
持有: * 字符串的长度(即 2 表示aa
) * 字符串的容量(即至少 2 表示aa
,因为那里已经有 2 个字符) * 指向包含实际字符的内存的指针
现在,如果您移动s1
到s2
,长度和容量以及指针将转移到s2
。但是没有地方说它s2
在内存中与s1
. 这是您在程序中观察到的。
但是,由于只有指针被移动到s2
,它仍然指向包含实际字符的同一内存。这可以通过检查来观察as_bytes
:
fn main() {
let s1 = String::from("aa");
println!("p2:{:p}", s1.as_bytes());
let s2 = s1;
println!("p2:{:p}", s2.as_bytes());
}
上面的程序吐出相同的内存地址。
推荐阅读
- python - Flask WTForms 用变量自动填充 StringField
- reactjs - 将 webpack-stream 与 gulp 一起使用时的奇怪行为
- powershell - 使用 powershell 获取对 Active Directory 分发列表的最新更改
- sas - sas ods --> ppt 总是'修复消息'
- c# - 无法将类型“void”隐式转换为“string”
- puppet - 为什么puppet中的exec资源的previous_value总是notrun?
- gradle - Gradle:shadowJar 将依赖项排除在外
- c++ - 条件变量中的 gcc 错误::wait_for
- mysql - 试图将西里尔符号插入 mysql 表
- vue.js - 使用动态 vue 输入的新值