我对我的代码有疑问:
pub fn get_signals(path: &String) -> Vec<Vec<f64>> {
let mut rdr = csv::ReaderBuilder::new().delimiter(b';').from_path(&path).unwrap();
let mut signals: Vec<Vec<f64>> = Vec::new();
for record in rdr.records(){
let mut r = record.unwrap();
for (i, value) in r.iter().enumerate(){
match signals.get(i){
Some(_) => {},
None => signals.push(Vec::new())
}
signals[i].push(value.parse::<f64>().unwrap());
}
}
signals
}
Rust如何处理返回?当我,例如写let signals = get_signal(&"data.csv".to_string());
时,Rust会假设我想要一个新的Vec实例(复制所有数据)或只是将指针传递给先前分配的(via Vec::new()
)内存?最有效的方法是什么?另外,rdr
会发生什么?我认为,鉴于Rusts的记忆安全,它被摧毁了。
答案 0 :(得分:4)
Rust如何处理返回?
唯一的保证Rust,即语言,在代码中没有明确的.clone()
,值永远不会克隆。因此,从语义的角度来看,值是移动,这不需要分配内存。
Rust是否假设我想要
Vec
的新实例(复制所有数据)或只是将指针传递给先前分配的(通过Vec::new()
)内存?
这是特定于实现的,是ABI(应用程序二进制接口)的一部分。 Rust ABI 不正式化,并且不稳定,因此没有标准描述它并且不能保证这种情况。
此外,这取决于函数调用是内联还是不是。如果函数调用是内联的,那么当然没有return
,但是应该观察到相同的行为。
对于小值,它们应该通过寄存器(或几个寄存器)返回。
对于较大的值:
注意:这里的大小是堆栈上的大小,由std::mem::size_of
返回;因此size_of::<Vec<_>>() == 24
在64位架构上。
最有效的方法是什么?
返回与单个调用的一样高效。
但是,如果您发现自己处于某种情况,例如,您希望逐行读取文件,则重用缓冲区从一次调用到另一种调用是有意义的要么:
&mut
提及String
或Vec<u8>
说明,重点是避免内存分配。