How to iterate and retrieve values ​​from a for loop in Rust

I am new to Rust and want to understand concepts such as borrowing. I am trying to create a simple two-dimensional array using standard input. 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 does not compile because the lifetime of the outputs variable 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 iterated values ​​from a block to an array of values?

+5
source share
2 answers

split() gives substrings (string fragments) taken from the original string, and the original string outputs from string 6.

  • String slices cannot survive the scope of outputs : when the loop iteration is complete, outputs freed. Since values more durable, slices cannot be stored there.
  • We cannot take slices of outputs through modifications to outputs . Thus, even if String outputs themselves were defined before values , we could not easily put line slices from .split() in values ; changing a line (reading into it) invalidates slices.

The decision should either

  • Use a nested String array, and when you assign an element from a shared iterator, create a String from &str using .to_string() . I would recommend this solution. (However, the String array is not so simple to work, perhaps this already requires the use of Vec .) 1
  • Read all the input before building the nested array &str , which takes from String input. It is good if a nested array is what you only need temporarily.

1 : instead of vec![vec![String::new(); 6]; 6] vec![vec![String::new(); 6]; 6] vec![vec![String::new(); 6]; 6] can use

+6
source

This answer was carried over from the question where he solved the needs of the OP.

 use std::io; fn main() { let mut values = vec![vec![String::new(); 6]; 6]; for i in 0..6 { let mut outputs = String::new(); io::stdin().read_line(&mut outputs) .expect("failed to read line"); let values_itr = outputs.trim().split(' '); let mut j = 0; for (_, value) in values_itr.enumerate() { values[i][j] = value.to_string(); j += 1; } } } 
+1
source

Source: https://habr.com/ru/post/1240069/


All Articles