Следующий код считывает записи с пространственным разделителем из stdin и записывает записи с разделителями-запятыми в stdout. Даже с оптимизированными строками он довольно медленный (примерно в два раза медленнее, чем использование, скажем, awk).
use std::io::BufRead;
fn main() {
let stdin = std::io::stdin();
for line in stdin.lock().lines().map(|x| x.unwrap()) {
let fields: Vec<_> = line.split(' ').collect();
println!("{}", fields.join(","));
}
}
Одним из очевидных улучшений было бы использование itertools
для объединения без выделения вектора (вызов collect
вызывает выделение). Однако я попробовал другой подход:
fn main() {
let stdin = std::io::stdin();
let mut cache = Vec::<&str>::new();
for line in stdin.lock().lines().map(|x| x.unwrap()) {
cache.extend(line.split(' '));
println!("{}", cache.join(","));
cache.clear();
}
}
Эта версия пытается повторно использовать один и тот же вектор снова и снова. К сожалению, компилятор жалуется:
error: `line` does not live long enough
--> src/main.rs:7:22
|
7 | cache.extend(line.split(' '));
| ^^^^
|
note: reference must be valid for the block suffix following statement 1 at 5:39...
--> src/main.rs:5:40
|
5 | let mut cache = Vec::<&str>::new();
| ^
note: ...but borrowed value is only valid for the for at 6:4
--> src/main.rs:6:5
|
6 | for line in stdin.lock().lines().map(|x| x.unwrap()) {
| ^
error: aborting due to previous error
Что, конечно, имеет смысл: переменная line
активна только в теле цикла for
, тогда как cache
хранит указатель на нее по итерациям. Но эта ошибка по-прежнему выглядит мне ложной: поскольку после каждой итерации кеш clear
ed, ссылка на line
не может быть сохранена, правильно?
Как я могу рассказать об этом чеку?