我有一些C经验,但我是Rust的新手 . 当我将一个struct传递给一个函数并从函数返回一个struct时,会发生什么?它似乎不“复制”结构,但如果没有复制,结构在哪里创建?它是在外部函数的堆栈中吗?
struct Point {
x: i32,
y: i32,
}
// I know it's better to pass in a reference here,
// but I just want to clarify the point.
fn copy_struct(p: Point) {
// Is this return value created in the outer stack
// so it won't be cleaned up while exiting this function?
Point {.. p}
}
fn test() {
let p1 = Point { x: 1, y: 2 };
// Will p1 be copied or does copy_struct
// just use a reference of the one created on the outer stack?
let p2 = copy_struct(p1);
}
2 回答
很长一段时间C程序员最近也和Rust一起玩,我知道你来自哪里 . 对我来说,重要的是要理解在Rust值vs引用是关于所有权,并且编译器可以调整调用约定以优化移动语义 .
因此,您可以在不在堆栈上复制的情况下传递值,但这会将所有权移动到被调用函数 . 它仍然在调用函数堆栈框架中,并且从C ABI角度来看它传递指针,但编译器强制执行该值在返回时永远不会再次使用 .
还有返回值优化,其中调用函数分配空间并将指针传递给调用者,调用者可以直接在那里填写返回值 . 这是C程序员用来手动处理的事情 .
因此,所有权规则和借用检查器的安全性,加上缺乏固定的保证ABI /调用约定,允许编译器生成有效的呼叫站点 . 通常你更担心所有权和生命周期,然后需要尝试并且聪明地调用函数调用堆栈行为 .
我不确定你在问什么 .
如果您的问题是关于您作为程序员的角度所创建的值发生了什么,那么答案是moved(除非它实现Copy) . 你可能想要通过一些基本的生锈教程来掌握这个概念 .
如果你在询问引擎盖下发生了什么,那么我担心可能没有单一的答案 . 我相信,从概念上讲,使用像
memcpy
之类的东西来复制值,但是优化器可能会启动并消除它 . 我不认为有关于此的规范,并且考虑这个实现细节可能更好 .