How can I pass an str read from the some file as an parameter of function with explicit lifetime?


#1

There is my code and problem rise at last some line.

use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::path::Path;
use std::collections::HashMap;

pub fn main() {
    let a = molecule_build("input");
}

pub struct Atom<'a> {
    pub symbol: &'a str,
    pub coor: (f64, f64, f64),
}

pub struct Molecule<'a> {
    pub atom_num: u64,
    pub atoms: HashMap<u64, Atom<'a>>, 
}

impl<'a> Molecule<'a> {
    pub fn new() -> Self {
        Molecule {
            atom_num: 0,
            atoms: HashMap::new(),
        }
    }

    pub fn add_atom(&mut self, symbol: &'a str, coor: (f64, f64, f64)) {
        let atom = Atom {symbol: symbol, coor: coor};
        self.atom_num += 1;
        self.atoms.insert(self.atom_num, atom);
    }
}

pub fn molecule_build<'a>(input_file: &'a str) -> Molecule {
    let mut mole = Molecule::new();

    let path = Path::new(input_file);
    let file = match File::open(&path) {
        Err(why) => panic!("couldn't open {}: {}", path.display(), Error::description(&why)),
        Ok(file) => file,
    };

    let reader = BufReader::new(file);
    
    for line in reader.lines().by_ref() {
        let symbol = line.as_ref().expect("element symbol");
        mole.add_atom(symbol.as_str(), (1.0, 1.0, 1.0));
    }

    mole
}

error is

error: `line` does not live long enough
  --> test1.rs:49:22
   |
49 |         let symbol = line.as_ref().expect("element symbol");
   |                      ^^^^ does not live long enough
50 |         mole.add_atom(symbol.as_str(), (1.0, 1.0, 1.0));
51 |     }
   |     - borrowed value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on the block at 37:59...
  --> test1.rs:37:60
   |
37 | pub fn molecule_build<'a>(input_file: &'a str) -> Molecule {

I want to know lifetime of some string or str read from input file?


#2

Like this, you can’t do it - reading lines from the file allocates Strings and they have to be owned by somebody - but your Molecule only contains references.

Either put owned Strings into the Atom (if you have situations where references would suffice, you can use Cow<str>), or you have save the allocated Strings in some other structure.

In the case of atom symbols, of course you might want to forgo strings completely and work with an enum, or a newtype wrapping an integer (the atomic number).