rust - 如何避免此程序的 for 循环和 let 语句

标签 rust

在 Rust 中,如何避免编写 for 循环和 let 语句?该程序用于记录该字符串出现在文本的哪一行以及出现在该行的位置。

我知道我可以用迭代器和map来消除它们,但是我刚接触Rust,我不知道怎么写。

pub struct L{
    x: usize,
    y: usize,
}
pub fn foo (text: &str, string: &str)->Vec<L> {
    let mut r= Vec::new();
    let mut x=0;
    for line in text.lines(){
        for (y, _) in line.match_indices(string){
            r.push(L{
                    x : x,
                    y: y, })
        }
        x+=1;
    }
    r
}

最佳答案

这等效于使用迭代器:

pub fn foo(text: &str, string: &str) -> Vec<L> {
    text.lines()
        .enumerate()
        .flat_map(|(x, line)| {
            line.match_indices(string).map(move |(y, _)| { L { x, y } })
        })
        .collect()
}

逐行分解:

.enumerate()

enumerate 用于转换 T 的迭代器进入 (usize, T) 的迭代器,基本上用索引压缩原始值。您这样做是因为您正在使用 x 跟踪行号。 .

.flat_map(|(x, line)| { ... })

flat_map 用于允许迭代器中的每个值返回其自己的迭代器,其值然后被展平到一个流中。

line.match_indices(string).map(move |(y, _)| { L { x, y } })

这里我们只是使用 map 采取xy并创建一个 L . move被使用是因为否则 x将为闭包借用,但迭代器和闭包将返回给 flat_map关闭,生命周期超过x . move只是复制 x所以这不是问题。

.collect()

collect 用于将迭代器转换为可以通过实现 FromIterator 从迭代器生成的东西, 通常是像 Vec 这样的集合.这也是通过知道我们返回一个 Vec<L> 来使用类型推断。 , 它知道收集到 Vec<L> .


您可以在 Rust Playground 上验证等价性.

关于rust - 如何避免此程序的 for 循环和 let 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64614968/

相关文章:

iterator - 返回 RefCell 中 Vec 的迭代器

rust - 在 Rust 中指向临时对象的原始指针可以吗?

compiler-errors - 包含具有特征参数的结构的框的大小

rust - 方法返回具有相同生命周期的结构迭代器的生命周期

rust - 基板RPC中的返回结构

rust - 为什么使用 Tcplistener 传入迭代器时 for 循环不退出

rust - 在一行代码中从 stdin 读取一行到一个字符串

rust - 根据同一 Vec 的其他元素删除 Vec 元素的最佳方法

node.js - Rust 中是否有类似 NodeJS 的 EventEmitter 的功能?

rust - “argument requires that `记录` is borrowed for ` 'static`”与tokio柴油一起使用归属关系时