Hi,
It's me again. I would like to clean up the nested, nested, nested if let
statements as shown in the this_works()
function in the playground code below, and replace it with the iterator chain as shown in the this_fails_to_compile()
function, but that, err, fails to compile.
I understand the error, but I don't know how to fix it.
Any thoughts?
--wpd
use regex::Regex;
use std::collections::BTreeSet;
use std::io::{BufRead, Cursor};
fn this_fails_to_compile() -> Vec<String>
{
let essid_re = Regex::new(r#"ESSID:"(.+)""#).expect("Fix the broken RE you wrote!");
let file = Cursor::new(b"first\n ESSID:\"ABC\"\nthird\n");
// Using the following gets a "returns a value referencing data owned by the current function" error
// on the `essid_re.captures(&line)` line
let networks: BTreeSet<_> = file // * Use a BTreeSet to eliminate duplicates and to sort
.lines() // * split the input into lines
.filter_map(Result::ok) // * only grab lines that convert to UTF-8 without error
.filter_map(|line| essid_re.captures(&line)) // * match lines containing ESSID:"(.+)" (discard lines not matching that)
.filter_map(|m| m.get(1)) // * grab the .+ part of ESSID"(.+)"
.map(|m| m.as_str().to_string()) // * convert it to a String
.collect(); // * and collect all of that into a Vec<String>
networks.into_iter().collect::<Vec<_>>() // * convert to Vec<String>
}
fn this_works() -> Vec<String> {
let essid_re = Regex::new(r#"ESSID:"(.+)""#).expect("Fix the broken RE you wrote!");
let file = Cursor::new(b"first\n ESSID:\"ABC\"\nthird\n");
let mut networks = BTreeSet::<_>::new();
for line in file.lines() {
if let Some(line) = line.ok() {
if let Some(m) = essid_re.captures(&line) {
if let Some(ssid) = m.get(1) {
networks.insert(ssid.as_str().to_string());
}
}
}
}
networks.into_iter().collect::<Vec<_>>()
}
fn main() {
println!("This works: {:#?}", this_works());
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0515]: cannot return value referencing function parameter `line`
--> src/main.rs:16:28
|
16 | .filter_map(|line| essid_re.captures(&line)) // * match lines containing ESSID:"(.+)" (discard lines not matching that)
| ^^^^^^^^^^^^^^^^^^-----^
| | |
| | `line` is borrowed here
| returns a value referencing data owned by the current function
For more information about this error, try `rustc --explain E0515`.
error: could not compile `playground` due to previous error