I have a function that reads in a file, and for each line adds it to a HashSet
of type &str
, but I can't work out how to tell the borrow checker to increase the lifetime.
Here's my function so far:
fn build_collection_set(reader: &mut BufReader<File>) -> HashSet<&str> {
let mut collection_set: HashSet<&str> = HashSet::new();
for line in reader.lines() {
let line = line.unwrap();
if line.len() > 0 {
collection_set.insert(&*line);
}
}
return collection_set;
}
How do I let Rust know I want to keep it around longer?
but I can't work out how to tell the borrow checker to increase the lifetime.
It's impossible.
The lifetime of a value, in C, C++ or Rust, is defined either:
You can create variables which reference this value, and if your reference lives longer than the value, then you have a dangling reference:
In order to validate your program, the Rust compiler will require that you annotate the lifetime of your references; you will use lifetime annotations such as 'a
in &'a T
which allow naming a lifetime in order to document the relationship between the lifetime of multiple values.
The operative word is document here: a lifetime is intangible and cannot be influenced, the lifetime annotation 'a
is just a name to allow referring to it.
So?
Whenever you find yourself wanting to extend the lifetime of a reference, what you should be looking at instead is extending the lifetime of the referred... or simply not use a reference but a value instead.
In this case, a simple solution is to return String
instead of &str
:
fn build_collection_set(reader: &mut BufReader<File>) -> HashSet<String> {
let mut collection_set = HashSet::new();
for line in reader.lines() {
let line = line.unwrap();
if line.len() > 0 {
collection_set.insert(line);
}
}
collection_set
}
reader.lines()
returns an iterator over owned Strings. But then in your for loop you cast these to borrowed references to &str
. So when the iterator goes out of scope all your borrowed references become invalid. Consider using a HashSet<String>
instead, which also is zero cost, because the Strings get moved into the HashSet and therefore aren't copied.
fn build_collection_set(reader: &mut BufReader<File>) -> HashSet<String> {
let mut collection_set: HashSet<String> = HashSet::new();
for line in reader.lines() {
let line = line.unwrap();
if line.len() > 0 {
collection_set.insert(line);
}
}
collection_set
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With