返回位置的值是否总是在父堆栈框架或接收框中分配?

时间:2015-07-19 15:04:30

标签: rust

我试图理解从方法返回时结构的行为。 “Rust Book”的nightlies部分中有一节说如果你使用了语法......

(... information about receiving by the server ...)
To: "Hidden recipients" <noreply@domain.com>
Subject: Een BCC
From: "My Name"<my@email.com>
Reply-To: my@email.com
Date: Sun, 19 Jul 2015 14:16:31 +0000
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="PHP-mixed"

..没有副本,因此不需要返回指针。但是当我开始玩它时,似乎不需要let x = box i_return_a_struct(); ,除非您需要在堆上存在该值。

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");
}

返回位置的值/结构是否总是在父堆栈框架或接收框中分配?

编辑:PS - 文档中是否有关于何时会发生复制省略的指导?

编辑:除了公认的解决方案之外,以下Q + A具有启发性:What are move semantics exactly?为我澄清了许多要点。

1 个答案:

答案 0 :(得分:2)

也许我不清楚你不理解的是什么。我想你明白了,但也许你还不知道:D

通常,函数的返回值(例如make_dummy)被压入堆栈。现在假设你想要堆上的对象。使用新的框语法,如果您希望堆上的对象,编译器可以进行一些优化。

现在让我们以书中的例子为例。

let y: Box<Dummy> = box make_dummy(some_dummy);

您可能认为在上面的示例中会发生以下情况:

  1. make_dummy的返回值写入堆栈(正常情况下)
  2. 分配一个框以包含Dummy对象
  3. 堆栈上的Dummy值被框对象复制到内存指针中。
  4. 使用旧的Box::new机制,这正是将要发生的事情。 相反,由于实验框语法,这发生了:

    1. 分配了一个框
    2. 指向该框的指针以某种方式传递给make_dummy函数(带有一些编译器魔法),因此返回值被直接写入盒装内存[没有额外的涉及堆栈的副本]
    3. 我希望现在更清楚了。