我试图了解从方法返回时结构的行为."Rust Book"的nightlies部分有一节说如果你使用了语法......
let x = box i_return_a_struct();
Run Code Online (Sandbox Code Playgroud)
..没有副本,因此不需要返回指针.但是当我开始玩它时,似乎box不需要它,除非你需要在堆上存在值.
#[derive(Debug)]
struct Dummy {
data: i64,
}
impl Drop for Dummy {
fn drop(&mut self) {
println!("{:?} is going out of scope", self as *const Dummy);
}
}
fn make_dummy(i: i64) -> Dummy {
Dummy { data: i }
}
fn main() {
{
let i = 15i32;
println!("{:?} is a variable on the stack frame", &i as *const i32);
let dummy1 = make_dummy(1);
println!("{:?} was returned and is being used", &dummy1 as *const Dummy);
let dummy2 = make_dummy(2);
println!("{:?} was returned and is being used", &dummy2 as *const Dummy);
let dummy3 = Box::new(make_dummy(3));
println!("{:?} box was returned and is being used", &(*dummy3) as *const Dummy);
let dummy4 = Box::new(make_dummy(4));
println!("{:?} box was returned and is being used", &(*dummy4) as *const Dummy);
}
println!("Leaving main");
}
Run Code Online (Sandbox Code Playgroud)
输出:
0x23fb94 is a variable on the stack frame
0x23faf8 was returned and is being used
0x23fa50 was returned and is being used
0x2825030 box was returned and is being used
0x2825040 box was returned and is being used
0x2825040 is going out of scope
0x2825030 is going out of scope
0x23fa50 is going out of scope
0x23faf8 is going out of scope
Leaving main
Run Code Online (Sandbox Code Playgroud)
返回位置的值/结构是否总是在父堆栈框架或接收框中分配?
编辑:PS - 在文档中是否有关于何时复制省略发生的任何指导?
编辑:除了公认的解决方案,以下Q + A具有启发性:什么是移动语义?为我澄清了许多要点.
也许我不清楚你不明白什么。我想你明白了,但也许你还不知道:D
通常,函数(make_dummy例如)的返回值被压入堆栈。现在假设您想要将对象放在堆上。使用新的盒语法,如果您希望对象位于堆上,编译器可以进行一些优化。
现在让我们看一下书中的例子。
let y: Box<Dummy> = box make_dummy(some_dummy);
Run Code Online (Sandbox Code Playgroud)
您可能认为在上面的示例中发生了以下情况:
make_dummy写入堆栈(通常)Dummy对象Dummy堆栈上的值由盒子对象复制到内存指针中。如果使用旧Box::new机制,这正是会发生的情况。相反,由于实验性的框语法,发生了这种情况:
make_dummy(使用一些编译器魔法),因此返回值直接写入装箱内存[没有涉及堆栈的额外副本]我希望现在更清楚了。