2
votes

When creating a new instance of a struct can you reference a previously initialized field within the struct under construction?

Example code:

use std::fs::File;
use std::io::BufReader;
use std::path::PathBuf;

#[derive(Debug)]
pub struct Test {
    file_handle: File,
    rdr: BufReader<File>,
}

impl Test {
    pub fn new(filepath: std::path::PathBuf) -> Self {
        Self {
            file_handle: File::open(&filepath)
                .expect(format!("Unable to open file {:?}", filepath).as_str()),
            rdr: BufReader::new(file_handle),
        }
    }
}

fn main() {
    let x = Test::new(PathBuf::from("my file"));
    println!("{:?}", x);
}

Error generated:

error[E0425]: cannot find value `file_handle` in this scope
  --> src/lib.rs:16:33
   |
16 |             rdr: BufReader::new(file_handle),
   |                                 ^^^^^^^^^^^ a field by this name exists in `Self`

Is there a specific pattern for this sort of thing, or is it just a Rust "no-no" (antithetical to the ideas of Rust)? How would something like this 'normally' be handled in Rust?

short: is a nono. Longer, the BufReader moves the File iirc, so even if you could this would still block what you wanted to do. - Netwave
You can, however, use variables in the constructor to store things and reference those. That still won't help you in this situation though, because File is not Copy and will be moved. - Herohtar
That makes sense, still getting used to the automatic transfer of ownership. stackoverflow.com/questions/33831265/… suggests I can access the file handle held by BufReader. - Dweeberly