0
votes

I'm trying to read a file into a vector, then print out a random line from that vector.

What am I doing wrong?

I'm asking here because I know I'm making a big conceptual mistake, but I'm having trouble identifying exactly where it is.

I know the error -

error[E0308]: mismatched types 26 | processor(&lines) | ^^^^^^ expected &str, found struct std::string::String

And I see that there's a mismatch - but I don't know how to give the right type, or refactor the code for that (very short) function.

My code is below:

use std::{
    fs::File,
    io::{prelude::*, BufReader},
    path::Path,
};

fn lines_from_file(filename: impl AsRef<Path>) -> Vec<String> {
    let file = File::open(filename).expect("no such file");
    let buf = BufReader::new(file);
    buf.lines()
        .map(|l| l.expect("Could not parse line"))
        .collect()
}

fn processor(vectr: &Vec<&str>) -> () {
    let vec = vectr;
    let index = (rand::random::<f32>() * vec.len() as f32).floor() as usize;

    println!("{}", vectr[index]);
}

fn main() {
    let lines = lines_from_file("./example.txt");
    for line in lines {
        println!("{:?}", line);
    }
    processor(&lines);
}
1

1 Answers

1
votes

While you're calling the processor function you're trying to pass a Vec<String> which is what the lines_from_file returns but the processor is expecting a &Vec<&str>. You can change the processor to match that expectation:

fn processor(vectr: &Vec<String>) -> () {
    let vec = vectr;
    let index = (rand::random::<f32>() * vec.len() as f32).floor() as usize;

    println!("{}", vectr[index]);
}

The main function:

fn main() {
    let lines = lines_from_file("./example.txt");
    for line in &lines {. //  &lines to avoid moving the variable
        println!("{:?}", line);
    }
    processor(&lines);
}

More generally, a String is not the same as a string slice &str, therefore Vec<String> is not the same as Vec<&str>. I'd recommend checking the rust book: https://doc.rust-lang.org/nightly/book/ch04-03-slices.html?highlight=String#string-slices