使用循环块外部枚举的索引

时间:2018-03-20 17:42:31

标签: for-loop scope rust enumerate

考虑这个解决Angelika Langer's article about generics and its usages的例子。

import pandas as pd
from matplotlib import pyplot as plt
import matplotlib.patches as mpatches

df = pd.DataFrame({'0':[0,1,0],'a':[1,2,3],'b':[2,4,6],'c':[5,3,1]})
colors = ['r','g','b']
fig, ax = plt.subplots()
ax.bar(df.index.values,df['0'].values, color = 'y')
ax2 = ax.twinx()
h = ax2.plot(df.index.values, df[['a','b','c']].values, color = colors)
handles = [mpatches.Patch(color='y')]
handles = handles + h
labels = df.columns()
lgd=ax.legend(handles,labels,loc='center left', bbox_to_anchor=(1.1, 0.5), ncol=1, fancybox=True, shadow=True, fontsize=ls)
plt.savefig('test.png', bbox_extra_artists=(lgd,tbx), bbox_inches='tight')

如何在循环块之外访问fn main() { // advent of code 1.2 2015 // you are at floor 0 // if instruction is ) go one floor up, else go one floor down // what index has the character that makes you go below floor 0 let instruction = ")))(((()))))"; let mut floor = 0; for (i, c) in input.chars().enumerate() { if c.to_string() == ")" { floor += 1; } else { floor -= 1; } if floor < 0 { break; } } // will fail println!("floor: {}", i) }

阅读Advent of Code 2015 1.2Understanding scope and shadowing matches后,我理解为什么我的代码失败,但我无法弄清楚如何处理它并使用{{1在街区之外。

我的问题是我还没有理解Rust中范围的目的吗?如果我想在循环范围之外使用它,我应该将循环置于函数内并返回i吗?

2 个答案:

答案 0 :(得分:3)

无法访问循环范围之外的循环变量。这不是一个&#34;问题&#34; Rust特有的;目前使用的大多数编程语言都有类似的范围规则,这些规则会导致同样的问题。

要解决您的first version of the problem,您应该&#34;返回&#34;索引,但你不需要一个功能。相反,您可以使用迭代器适配器:

fn main() {
    let maze = "***#***";

    let i = maze
        .chars()
        .enumerate()
        .find(|&(_, c)| c == '#')
        .map(|(i, _)| i);

    println!("# is at position: {:?}", i) // Some(3)
}

请注意,这会返回Option来处理找不到字母的情况。

要解决您的second version of the problem,您应该&#34;返回&#34;索引,但你不需要一个功能。相反,您可以使用迭代器适配器:

fn main() {
    let instruction = ")))(((()))))";
    let mut floor = 0;

    let i = instruction
        .chars()
        .enumerate()
        .find(|&(_, c)| {
            if c == ')' {
                floor += 1;
            } else {
                floor -= 1;
            }

            floor < 0
        })
        .map(|(i, _)| i);

    println!("floor: {:?}", i) // Some(6)
}

请注意,这会返回Option来处理未找到楼层的情况。

当然,您可以选择使用功能并尽早返回。做任何可以理解的事情。

答案 1 :(得分:2)

您不需要将代码放在函数中以获取i,您只需将其分配给新变量:

fn main() {
    let instruction = ")))(((()))))";
    let mut floor = 0;
    let mut breaking_index = None;

    for (i, c) in instruction.chars().enumerate() {
        if c.to_string() == ")" {
            floor += 1;
        } else {
            floor -= 1;
        }
        if floor < 0 {
            breaking_index = Some(i);
            break;
        }
    }

    // will not fail
    println!("floor: {:?}", breaking_index)
}