I'm new to Rust and looking to understand concepts like borrowing. I'm trying to create a simple two dimensional array using standard input. The code:
use std::io;
fn main() {
let mut values = [["0"; 6]; 6]; // 6 * 6 array
// iterate 6 times for user input
for i in 0..6 {
let mut outputs = String::new();
io::stdin().read_line(&mut outputs).expect(
"failed to read line",
);
// read space separated list 6 numbers. Eg: 5 7 8 4 3 9
let values_itr = outputs.trim().split(' ');
let mut j = 0;
for (_, value) in values_itr.enumerate() {
values[i][j] = value;
j += 1;
}
}
}
This won't compile because the outputs
variable lifetime is not long enough:
error[E0597]: `outputs` does not live long enough
--> src/main.rs:20:5
|
14 | let values_itr = outputs.trim().split(' ');
| ------- borrow occurs here
...
20 | }
| ^ `outputs` dropped here while still borrowed
21 | }
| - borrowed value needs to live until here
How can I get the iterated values out of the block into values array?
This answer was moved from the question, where it solved the OPs needs.
split()
gives you substrings (string slices) borrowed from the original string, and the original string isoutputs
from line 6.outputs
: when a loop iteration ends,outputs
is deallocated. Sincevalues
is longer lived, the slices can't be stored there.outputs
across a modification ofoutputs
. So even if theString
outputs
itself was defined beforevalues
, we couldn't easily put the string slices from.split()
intovalues
; modifying the string (reading into it) invalidates the slices.A solution needs to either
String
, and when you assign an element from the split iterator, make aString
from the&str
using.to_string()
. I would recommend this solution. (However an array ofString
is not at as easy to work with, maybe already this requires usingVec
instead.) 1&str
that borrows from the inputString
. This is good if the nested array is something that you only need temporarily.1: You can use something like
vec![vec![String::new(); 6]; 6]
instead