Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Dealing with clone in rust

I’m trying to iterate over a VCF file and create vectors with the data to build a DataFrame.

However, the rust compilator is raising an error saying that the borrowed value does not live enough.

I’m cloning the value because, in that case, I’m borrowing the vcf record as immutable and as mutable at the same time.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I don’t know how to proceed. Below there are the snippet of my code and the error.

use flate2::read::MultiGzDecoder;
use std::fs::File;
use std::io::BufReader;
mod vcf_reader;
use vcf::{VCFReader, U8Vec, VCFHeaderFilterAlt, VCFError, VCFRecord};

use vcf_reader::reader::VCFSamples;
use polars_core::prelude::*;
use std::time::Instant;
    
fn main() -> Result<()>  {
    let now = Instant::now();
    let mut reader = VCFReader::new(BufReader::new(File::open(
       "C:\\Users\\Desktop\\rust_lectures\\vcf_reader\\vcf_reader\\*.vcf"
    )?)).unwrap();


    // prepare VCFRecord object
    let mut vcf_record = VCFRecord::new(reader.header());

    // read one record
    let mut chromosome = Vec::new();
    let mut position = Vec::new();
    let mut id = Vec::new();
    let mut reference = Vec::new();
    let mut alternative = Vec::new();
    let result: bool = reader.next_record(&mut vcf_record).unwrap();
    loop {
        let row = vcf_record.clone();
        if result == false {
            let df = df!(
                "Chromosome" => chromosome,
                "Position" => position,
                "Id" => id,
                "Reference" => reference,
                "Alternative" => alternative,
        
            );
            println!("{:?}", df);
            let elapsed = now.elapsed();
            println!("Elapsed: {:.2?}", elapsed);
            return Ok(())
        } else {
            
            chromosome.push(String::from_utf8_lossy(&row.chromosome));
            position.push(&row.position);
            id.push(String::from_utf8_lossy(&row.id[0]));
            reference.push(String::from_utf8_lossy(&row.reference));
            alternative.push(String::from_utf8_lossy(&row.alternative[0]));
            
        }
        reader.next_record(&mut vcf_record).unwrap();
        
    }
error[E0597]: `row.chromosome` does not live long enough
  --> src\main.rs:44:53
   |
44 |             chromosome.push(String::from_utf8_lossy(&row.chromosome));
   |             ----------------------------------------^^^^^^^^^^^^^^^^^^^^--
   |             |                                       |
   |             |                                       borrowed value does not live long enough
   |             borrow later used here
...
50 |         }
   |         - `row.chromosome` dropped here while still borrowed

>Solution :

I’m cloning the value because

The problem is that you’re cloning the record but then you’re storing references into your arrays. Since those are references to the cloned record, they only live until the end of the block.

So either:

  • move the attributes out of the clone (essentially explode it)
  • or rather than working with a copy of the record, copy individual fields out of the base vcf_record

Either way you’re also misusing from_utf8_lossy: it always returns a reference-ish, because it avoids allocating if the input is valid utf8 (in that case it essentially just returns a reference to the original data).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading