rust - 迭代器、懒惰和所有权

标签 rust

我刚开始使用 Rust,我正在玩弄 regex crate 以便我可以创建词法分析器。

词法分析器使用一个大的正则表达式,其中包含一堆命名的捕获组。我正在尝试获取正则表达式的结果并创建一个 Vec<&str, &str>捕获名称和捕获值,但我一直遇到有关在映射和过滤结果时迭代返回的值的生命周期的问题。

我认为这与懒惰以及超出范围时迭代器未被消耗的事实有关,但我不确定如何实际解决问题。

extern crate regex;

use regex::Regex;

fn main() {
    // Define a regular expression with a bunch of named capture groups
    let expr = "((?P<num>[0-9]+)|(?P<str>[a-zA-Z]+))";
    let text = "0ab123cd";
    let re = Regex::new(&expr).unwrap();

    let tokens: Vec<(&str, &str)> = re.captures_iter(text)
        .flat_map(|t| t.iter_named())
        .filter(|t| t.1.is_some())
        .map(|t| (t.0, t.1.unwrap()))
        .collect();

    for token in tokens {
        println!("{:?}", token);
    }
}

运行上述代码会导致以下错误:

$ cargo run
Compiling hello_world v0.0.1 (file:///Users/dowling/projects/rust_hello_world)

src/main.rs:14:23: 14:24 error: `t` does not live long enough
src/main.rs:14         .flat_map(|t| t.iter_named())
                                     ^
src/main.rs:17:19: 22:2 note: reference must be valid for the block suffix following statement 3 at 17:18...
src/main.rs:17         .collect();
src/main.rs:18 
src/main.rs:19     for token in tokens {
src/main.rs:20         println!("{:?}", token);
src/main.rs:21     }
src/main.rs:22 }
src/main.rs:14:23: 14:37 note: ...but borrowed value is only valid for the block at 14:22
src/main.rs:14         .flat_map(|t| t.iter_named())
                                     ^~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `hello_world`.

最佳答案

你的情况的限制点是 .iter_named() 方法:

fn iter_named(&'t self) -> SubCapturesNamed<'t>

注意 &'t self:输出的生命周期将与 Captures 实例的生命周期相关联。这是因为名称存储在 Capture 对象中,因此它们的任何 &str 都不能超过此对象。

只有一个解决方法:您必须保持 Capture 实例处于事件状态:

let captures = re.captures_iter(text).collect::<Vec<_>>();
let tokens: Vec<(&str, &str)> = captures.iter()
    .flat_map(|t| t.iter_named())
    .filter(|t| t.1.is_some())
    .map(|t| (t.0, t.1.unwrap()))
    .collect();

关于rust - 迭代器、懒惰和所有权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29467320/

相关文章:

initialization - 为什么编译器会警告未初始化的变量,即使我已经分配了该变量的每个字段?

enums - 如何在 Rust 中的通用类型枚举上实现 fmt::Display?

rust - 如何使用 zbus 列出 block 设备?

process - 如何在不阻塞 Rust 的情况下读取子进程的输出?

rust - 在尝试读取STDIN缓冲区之前,是否有Rust方法来检查STDIN缓冲区是否为空?

tcp - 在Tokio中使用TcpStream读取碎片化的TCP数据包

syntax - @ 符号在 Rust 声明宏中意味着什么?

rust - `while let Ok(t) ... = try_read!(...)` 使读取循环更整洁

loops - 是否可以在每次迭代时步进不同的量而无需创建特殊的迭代器?

docker - 无法部署到 docker - 加密失败并且找不到 Rust 编译器