This Rust program collects words/lines from the user, and adds each to the variable line_set
. I'd like to change the code to trim each word before adding it to line_set
.
use std::collections::HashSet;
use std::io;
fn main() {
let mut line_set = HashSet::new();
for i in 1..4 {
let mut line = String::new();
io::stdin()
.read_line(&mut line)
.expect("Failed to read line");
//let line = line.trim();
line_set.insert(line.clone());
if i == 3 {
for l in &line_set {
println!("{}", l);
}
}
}
}
When I try to add a call to String::trim
, applied to the current word, the program no longer compiles:
error[E0597]: `line` does not live long enough
--> src/main.rs:12:20
|
12 | let line = line.trim();
| ^^^^ borrowed value does not live long enough
13 | line_set.insert(line.clone());
| -------- borrow later used here
...
19 | }
| - `line` dropped here while still borrowed
I used rustc
's --explain
switch, and it relates that "This error occurs because a value was dropped while it was still borrowed". I had hoped using the clone
method would avoid that problem. How do I get past the error?
str::trim
just produces a slice, not another String
, so when you call clone
on it, you're calling &str
's implementation of Clone
, which just copies the &str
(a cheap pointer copy). Instead, you should use one of the methods to turn the &str
into a String
, such as to_string
, to_owned
or more verbosely, String::from
.
use std::collections::HashSet;
use std::io;
fn main() {
let mut line_set = HashSet::new();
for i in 1..4 {
let mut line = String::new();
io::stdin()
.read_line(&mut line)
.expect("Failed to read line");
line_set.insert(line.trim().to_owned());
if i == 3 {
for l in &line_set {
println!("{}", l);
}
}
}
}