AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 78369598
Accepted
thefrollickingnerd
thefrollickingnerd
Asked: 2024-04-23 10:14:20 +0800 CST2024-04-23 10:14:20 +0800 CST 2024-04-23 10:14:20 +0800 CST

将值传出迭代器而不停止迭代

  • 772

我有一个解析输入字符串的函数:

fn parse_input(s: &str) -> ((usize, usize), BTreeMap<(usize, usize), Tile>){
 let mut start: (usize, usize) = (0,0);
 let grid = s.split("\n").enumerate().flat_map(|(r,l)| {
     l.chars().enumerate().map(move |(col, c)| {
         let t = classify_tile(c);
         match t {
             Tile::Start => {
                  *start = (r, col);
                  ((r,col), t)
                 },
             _ => ((r,col), t) 
         }
     })
 }).collect::<BTreeMap<(usize, usize), Tile>>();
 (start, grid)
}

我基本上想捕获起始图块的 r 和 col 值(这是唯一的,仅出现一次)。但目前,如果我尝试修改迭代器内的元组,我假设由于借用和范围原因,该值不会在迭代器外部修改。不过,迭代器完成很重要。

另一种解决方案是随后在 btreemap 中搜索起始图块,但我希望有一个更有效的解决方案。

我应该将其作为嵌套 for 循环吗?这里的迭代实际上是否更有效?

编辑:classify_tile 函数返回枚举类型。开始,土壤或管道。*start = (r,col) 部分不起作用。这是我试图解决这个问题的尝试。其他一切都可以。

dictionary
  • 1 1 个回答
  • 28 Views

1 个回答

  • Voted
  1. Best Answer
    vallentin
    2024-04-23T12:03:48+08:002024-04-23T12:03:48+08:00

    如果您稍微重构一下迭代器,您就可以做您想做的事。


    但我们首先要解决问题是什么。

    作为一个更简单的例子,让我们计算所有大写字母(以一种愚蠢的方式):

    let text = "Hello World";
    
    let mut count = 0;
    
    text.split_whitespace()
       .flat_map(|s| {
            s.chars().map(|c| {
                if c.is_uppercase() {
                    count += 1;
                }
            })
        })
        .for_each(|_| {});
    
    assert_eq!(count, 2);
    

    如果我们尝试编译它,我们会遇到与您相同的问题:

    error: captured variable cannot escape `FnMut` closure body
      --> src\main.rs:85:13
       |
    80 |       let mut count = 0;
       |           --------- variable defined here
    ...
    84 |           .flat_map(|s| {
       |                       - inferred to be a `FnMut` closure
    85 | /             s.chars().map(|c| {
    86 | |                 if c.is_uppercase() {
    87 | |                     count += 1;
       | |                     ----- variable captured here
    88 | |                 }
    89 | |             })
       | |______________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body
       |
       = note: `FnMut` closures only have access to their captured variables while they are executing...
       = note: ...therefore, they cannot allow references to captured variables to escape
    

    这是为什么?

    给定的闭包map()需要可变借用count,这本身就很好。

    flat_map()当我们加入其中时,问题就出现了。因为flat_map()可能会产生多个迭代器。每个生成的迭代器都需要可变借用count。这当然是不允许的,因为我们不能多次借用任何东西。


    总的来说,这个问题很容易解决,你只需重构迭代器:

    text.split_whitespace()
        .flat_map(|s| s.chars())
        .map(|c| {
            if c.is_uppercase() {
                count += 1;
            }
        })
        .for_each(|_| {});
    

    或者

    text.split_whitespace()
        .map(|s| s.chars())
        .flatten()
        .map(|c| {
            if c.is_uppercase() {
                count += 1;
            }
        })
        .for_each(|_| {});
    

    为你的迭代器解决这个问题,可能看起来像这样:

    let grid = s
        .split("\n")
        .enumerate()
        .flat_map(|(r, l)| {
            l.chars().enumerate().map(move |(col, c)| {
                let t = classify_tile(c);
                match t {
                    Tile::Start => ((r, col), t),
                    _ => ((r, col), t),
                }
            })
        })
        .inspect(|((r, col), t)| match t {
            Tile::Start => {
                start = (*r, *col);
            }
            _ => {}
        })
        .collect::<BTreeMap<(usize, usize), Tile>>();
    

    或者

    let grid = s
        .split("\n")
        .enumerate()
        .flat_map(|(r, l)| l.chars().enumerate().map(move |(col, c)| ((r, col), c)))
        .map(|((r, col), c)| {
            let t = classify_tile(c);
            match t {
                Tile::Start => {
                    start = (r, col);
                    ((r, col), t)
                }
                _ => ((r, col), t),
            }
        })
        .collect::<BTreeMap<(usize, usize), Tile>>();
    

    它可以有多种写法。

    • 1

相关问题

  • 是否可以在映射块中使用数组的索引?

  • 如何在 mulesoft dataweave 中创建增量计数器

  • 映射如何通过不可变引用获取部分所有权

  • GO,地图键已全部更新

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    为什么这个简单而小的 Java 代码在所有 Graal JVM 上的运行速度都快 30 倍,但在任何 Oracle JVM 上却不行?

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    何时应使用 std::inplace_vector 而不是 std::vector?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Martin Hope
    Aleksandr Dubinsky 为什么 InetAddress 上的 switch 模式匹配会失败,并出现“未涵盖所有可能的输入值”? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge 为什么这个简单而小的 Java 代码在所有 Graal JVM 上的运行速度都快 30 倍,但在任何 Oracle JVM 上却不行? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini 具有指定基础类型但没有枚举器的“枚举类”的用途是什么? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer 何时应使用 std::inplace_vector 而不是 std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB 为什么 GCC 生成有条件执行 SIMD 实现的代码? 2024-02-17 06:17:14 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve