【发布时间】:2021-04-08 08:52:04
【问题描述】:
当 rust 执行 memcpy 并调用 drop 函数时,我感到很困惑。我阅读了一些相关页面,但没有找到对此的详细描述。
下面是一些简单的代码:
struct MyType {
name: String,
age: i32
}
impl MyType {
fn new() -> Self {
let tmp = MyType {
name: String::from("Joy"),
age: 1
};
let addr = &tmp as *const MyType as usize;
println!("Calling new.");
println!("tmp : name: {}, age: {}", tmp.name, tmp.age);
println!("addr: 0x{:X}\n",addr);
tmp
}
}
impl Drop for MyType {
fn drop(&mut self) {
println!("Calling drop.\n");
}
}
fn main() {
println!("");
let a = MyType{
name: String::from("Tom"),
age : 10
};
let addr = &a as *const MyType as usize;
println!(" a : name: {}, age: {}", a.name, a.age);
println!("addr: 0x{:X}\n",addr);
let mut b = a;
let addr = &b as *const MyType as usize;
println!(" b : name: {}, age: {}", b.name, b.age);
println!("addr: 0x{:X}\n",addr);
b = MyType::new();
let addr = &b as *const MyType as usize;
println!(" b : name: {}, age: {}", b.name, b.age);
println!("addr: 0x{:X}\n",addr);
let c = MyType::new();
let addr = &c as *const MyType as usize;
println!(" c : name: {}, age: {}", c.name, c.age);
println!("addr: 0x{:X}\n",addr);
b = c;
let addr = &b as *const MyType as usize;
println!(" b : name: {}, age: {}", b.name, b.age);
println!("addr: 0x{:X}\n",addr);
}
然后输出:
> Executing task: cargo run --package hello_world --bin hello_world <
Compiling hello_world v0.1.0 (/home/dji/proj_learn_rust/hello_world)
Finished dev [unoptimized + debuginfo] target(s) in 0.21s
Running `target/debug/hello_world`
a : name: Tom, age: 10
addr: 0x7FFDB8636AF0
b : name: Tom, age: 10
addr: 0x7FFDB8636BE0
Calling new.
tmp : name: Joy, age: 1
addr: 0x7FFDB8636CB8
Calling drop.
b : name: Joy, age: 1
addr: 0x7FFDB8636BE0
Calling new.
tmp : name: Joy, age: 1
addr: 0x7FFDB8636DB0
c : name: Joy, age: 1
addr: 0x7FFDB8636DB0
Calling drop.
b : name: Joy, age: 1
addr: 0x7FFDB8636BE0
Calling drop.
-
let mut b = a;之后,好像a和b的地址不一样。为什么不直接将a的内存转移到b执行move操作,a已经失效了?似乎在使用let关键字时进行了浅拷贝(如 C 中的 memcpy),而没有调用 drop 函数。 -
c和tmp的地址相同。这时候好像是执行了真正的move,而不是memcpy,没有调用drop函数。 -
但是为什么
b = c;调用drop 函数而let mut b = a;和let c = MyType::new();不调用呢?
let 是否避免挂断电话?
【问题讨论】:
-
您不使用
--release标志来启用优化。未优化代码的行为方式几乎与源代码相同
标签: rust binding compiler-construction assign