Rust 如何将结构体作为函数参数和返回值处理? [英] How does Rust deal with structs as function parameters and return values?

查看:67
本文介绍了Rust 如何将结构体作为函数参数和返回值处理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 C 方面有一些经验,但我是 Rust 的新手.当我将结构体传递给函数并从函数返回结构体时,幕后会发生什么?似乎它没有复制"结构,但如果它没有被复制,那么结构在哪里创建?是否在外层函数的栈中?

I have some experience in C, but I'm new to Rust. What happens under the hood when I pass a struct into a function and I return a struct from a function? It seems it doesn't "copy" the struct, but if it isn't copied, where is the struct created? Is it in the stack of the outer function?

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

推荐答案

作为最近也在玩 Rust 的长期 C 程序员,我理解您的想法.对我来说,要理解的重要一点是,在 Rust 中,值与引用是关于所有权的,编译器可以调整调用约定以优化移动语义.

As a long time C programmer also playing with Rust recently, I understand where you're coming from. For me the important thing to understand was that in Rust value vs reference are about ownership, and the compiler can adjust the calling conventions to optimize around move semantics.

所以你可以传递一个值而不在堆栈上复制,但这会将所有权转移到被调用的函数.它仍然在调用函数的堆栈框架中,从 C ABI 的角度来看,它正在传递一个指针,但编译器强制要求在返回时不再使用该值.

So you can pass a value without it making a copy on the stack, but this moves the ownership to the called function. It's still in the calling functions stack frame, and from a C ABI perspective it's passing a pointer, but the compiler enforces that the value is never used again upon return.

还有返回值优化,调用函数分配空间并将指针传递给调用者,调用者可以直接在那里填写返回值.这是 C 程序员习惯于手动处理的事情.

There's also return value optimization, where the calling function allocates space and the pointer is passed to the caller which can fill out the return value there directly. This is the sort of thing a C programmer would be used to handling manually.

因此所有权规则和借用检查器的安全性,加上缺乏固定的保证 ABI/调用约定,允许编译器生成有效的调用站点.通常,您更担心所有权和生命周期,然后需要尝试巧妙处理函数调用堆栈行为.

So the safety of the ownership rules and borrow checker, combined with the lack of a fixed guaranteed ABI/calling convention, allow the compiler to generate efficient call sites. And generally you worry more about ownership and lifetime, then needing to try and be clever about function call stack behavior.

这篇关于Rust 如何将结构体作为函数参数和返回值处理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆