我正在尝试了解 Rust 中内存的来龙去脉。当在函数内部创建向量然后返回时,是返回引用还是复制整个向量?
例子:
use std::io;
fn line_to_ints() -> Vec<u32> {
let mut line = String::new();
io::stdin()
.read_line(&mut line)
.expect("Failed to read line");
return line
.split(" ")
.map(|x| x.parse().expect("Not an integer!"))
.collect();
}
对于所有其他非原始数据类型,此处的返回行为是否也相同?
不同于Is there any way to return a reference to a variable created in a function? ,我想更多地了解引擎盖下发生的事情。该问题的答案没有明确说明是否创建了向量然后将其复制到新位置,或者是否返回了指针的所有权我知道向量是在堆上创建的所以我想涉及一个指针。
最佳答案
is a reference returned
没有。这不可能是因为函数结束后没有什么可以引用。这在 Is there any way to return a reference to a variable created in a function? 中有详细介绍。 .
is the entire vector copied
是的,但可能不是您的意思。 Vec
基本上定义为
struct Vec<T> {
capacity: usize,
length: usize,
data: *mut T,
}
从语义上讲,这 3 个指针大小的字段从函数移动到调用者。 vector包含的N个元素不被复制。
在实现方面,编译器/优化器可以从一大堆技巧中挑选:
- 实际复制所有三个字段
- 传入一个 secret 的可变引用并让函数直接写入它
- 在调用函数的地方内联
- 执行死代码删除并且从一开始就不要调用该函数
- 可能还有其他人...
了解它选择哪个的唯一方法是查看 MIR/LLVM IR/程序集。
Will the return behavior here also be the same for all other non-primitive data types?
是的。 Rust 的数据类型都是一样的。原始与非原始对于语言的语义没有任何意义。
另见:
关于memory - 在幕后,Rust 中的向量是通过引用还是值返回的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52267429/