完全生锈如何处理返回值

时间:2018-03-27 10:27:36

标签: rust runtime

我对我的代码有疑问:

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的记忆安全,它被摧毁了。

1 个答案:

答案 0 :(得分:4)

  

Rust如何处理返回?

唯一的保证Rust,即语言,在代码中没有明确的.clone(),值永远不会克隆。因此,从语义的角度来看,值是移动,这不需要分配内存。

  

Rust是否假设我想要Vec的新实例(复制所有数据)或只是将指针传递给先前分配的(通过Vec::new())内存?

这是特定于实现的,是ABI(应用程序二进制接口)的一部分。 Rust ABI 正式化,并且稳定,因此没有标准描述它并且不能保证这种情况。

此外,这取决于函数调用是内联还是不是。如果函数调用是内联的,那么当然没有return,但是应该观察到相同的行为。

对于小值,它们应该通过寄存器(或几个寄存器)返回。

对于较大的值

  • 调用者应该在堆栈上保留内存(正确调整大小并对齐)并将指向该区域的指针传递给被调用者,
  • 然后被调用者将在指向的位置构造返回值,这样当它返回时,该值就存在,供调用者使用。

注意:这里的大小是堆栈上的大小,由std::mem::size_of返回;因此size_of::<Vec<_>>() == 24在64位架构上。

  

最有效的方法是什么?

返回与单个调用的一样高效

但是,如果您发现自己处于某种情况,例如,您希望逐行读取文件,则重用缓冲区从一次调用到另一种调用是有意义的要么:

  • 对缓冲区&mut提及StringVec<u8>说明,
  • 或按值取缓冲并返回。

重点是避免内存分配。