在循环块外使用 enumerate 的索引
Using the index from enumerate outside the loop block
考虑这个求解 Advent of Code 2015 1.2 的例子。
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)
}
如何在循环块外访问i
?
读过 and this chapter of the book,我理解为什么我的代码失败了,但我不知道如何处理它并在外面使用i
街区。
我的问题是我没有理解 Rust 中作用域的用途吗?如果我想在循环范围之外使用它,我是否应该将循环放在函数内部,return i
?
您不能访问循环范围之外的循环变量。这不是 Rust 独有的 "problem";当今使用的大多数编程语言都有类似的范围规则,这些规则会导致相同的问题。
要解决你的 first version of the problem,你应该 "return" 索引,但你不需要一个函数。相反,您可以使用迭代器适配器:
fn main() {
let maze = "***#***";
let i = maze
.chars()
.enumerate()
.find(|&(_, c)| c == '#')
.map(|(i, _)| i);
println!("# is at position: {:?}", i) // Some(3)
}
请注意,这 return 是一个 Option
来处理找不到字母的情况。
要解决您的 second version of the problem,您应该 "return" 索引,但您不需要函数。相反,您可以使用迭代器适配器:
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)
}
请注意,这 return 是一个 Option
来处理找不到地板的情况。
当然,你可以选择早点用一个函数,return。做任何你能理解的事情。
您无需将代码放入函数中即可获得 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)
}
考虑这个求解 Advent of Code 2015 1.2 的例子。
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)
}
如何在循环块外访问i
?
读过i
街区。
我的问题是我没有理解 Rust 中作用域的用途吗?如果我想在循环范围之外使用它,我是否应该将循环放在函数内部,return i
?
您不能访问循环范围之外的循环变量。这不是 Rust 独有的 "problem";当今使用的大多数编程语言都有类似的范围规则,这些规则会导致相同的问题。
要解决你的 first version of the problem,你应该 "return" 索引,但你不需要一个函数。相反,您可以使用迭代器适配器:
fn main() {
let maze = "***#***";
let i = maze
.chars()
.enumerate()
.find(|&(_, c)| c == '#')
.map(|(i, _)| i);
println!("# is at position: {:?}", i) // Some(3)
}
请注意,这 return 是一个 Option
来处理找不到字母的情况。
要解决您的 second version of the problem,您应该 "return" 索引,但您不需要函数。相反,您可以使用迭代器适配器:
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)
}
请注意,这 return 是一个 Option
来处理找不到地板的情况。
当然,你可以选择早点用一个函数,return。做任何你能理解的事情。
您无需将代码放入函数中即可获得 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)
}