我正在阅读Rust指南的return pointers part。 以下是它的示例代码:
struct BigStruct {
one: int,
two: int,
// etc
one_hundred: int,
}
fn foo(x: Box<BigStruct>) -> BigStruct {
return *x;
}
fn main() {
let x = box BigStruct {
one: 1,
two: 2,
one_hundred: 100,
};
let y = box foo(x);
}
以下解释的重点部分让我困惑:
此代码中没有副本。 main为`box分配足够的空间,将指向该内存的指针传递给foo为x,然后foo将值直接写入该指针。这会将返回值直接写入分配的框中。
阅读a related question后,我仍然没有在此处获得 no-copy 点。
函数foo
是否会返回*x
的副本?
如果是的话,如何理解解释?
如果没有,是否与所有权和借款相关?
我理解所有权和借款的概念,我只是不知道它何时发生。
答案 0 :(得分:4)
本指南试图告诉您代码的行为就像是以这种方式编写的:
struct BigStruct {
one: int,
two: int,
// etc
one_hundred: int,
}
fn foo(x: Box<BigStruct>, result: &mut BigStruct) {
*result = *x;
}
fn main() {
let x = box BigStruct {
one: 1,
two: 2,
one_hundred: 100,
};
unsafe {
let mut y = box std::mem::uninitialized();
foo(x, &mut *y);
}
}
main
创建一个Box
并将指向框内部的指针传递给foo
作为输入参数。这样,foo
可以直接将结果值存储在那里,而不是将其返回并将main
复制到框中。
在foo
(从第一个框到第二个框)中发生了一个副本,但如果foo
没有直接写入框中,则会有两个副本(可能有一个副本) foo
中堆栈的第一个框,然后从堆栈到main
中的第二个框。)
P.S。:我认为指南中有错误。它说:
将指向该内存的指针传递给foo,如 x
但x
是我们尝试复制的框,而不是新框...而是将指针作为隐藏参数传递。