提问人:Pioneer_11 提问时间:11/5/2023 更新时间:11/10/2023 访问量:60
Rust 函数从嵌套迭代器中返回
rust function return from within a nested iterator
问:
我有一个函数,可以从 9 x 9 的数字网格创建数独网格。如果发现一个无效的数字,它应该返回有关该数字所在位置的信息(其功能在注释掉的代码中)。代码当前正在运行,但如果使用注释掉的代码来替换,则编译器会吐出一系列错误,这些错误(如果我解释正确的话)表明 正在返回值 to 而不是从 。我怎样才能解决这个问题,使其按预期工作?谢谢.unwrap()
return
std::array::from_fn
unsolved_sudoku_from_nums
/// parse nums into an UnsovedSudoku, 1-9 will be parsed as values 1-9, 0 will be parsed as an unsolved cell and all
/// other values will cause the function to return an InvalidInt error.
fn unsolved_sudoku_from_nums(nums: &[[u8; 9]; 9]) -> Result<UnsolvedSudoku, InvalidInt> {
Ok(UnsolvedSudoku (
std::array::from_fn(|i|{
std::array::from_fn(|j| {
match nums[i][j] {
0 => WorkingCell::PossibleValues([true; 9]),
int => WorkingCell::Solved(
SudokuValue::from_int(int)
.unwrap()
// .expect(
// return Err(InvalidInt{
// row: i,
// column: j,
// int: nums[i][j],
// })
// )
),
}
})
})
))
}
仅供参考
struct UnsolvedSudoku (
[[WorkingCell; 9]; 9]
);
答:
1赞
cdhowie
11/7/2023
#1
如果数组中的元素类型实现了,则可以编写一个非常简单的不稳定标准库函数的实现,它不像 那样优化,但不需要不安全的代码:Default
std::array::try_from_fn()
try_from_fn
fn array_try_from_fn<const N: usize, T, E, F>(mut f: F) -> Result<[T; N], E>
where
T: Default,
F: FnMut(usize) -> Result<T, E>,
{
let mut arr = std::array::from_fn(|_| T::default());
for i in 0..N {
arr[i] = f(i)?;
}
Ok(arr)
}
这为您提供了标准库函数的人体工程学设计,并允许您在稳定时轻松更换此功能。try_from_fn
评论
1赞
Filipe Rodrigues
11/7/2023
对于更复杂的情况,其中 ,但仍然(例如)可用于创建初始数组T: !Copy
T: Default
Vec<T>
std::array::from_fn(|_| T::default())
0赞
Pioneer_11
11/10/2023
@FilipeRodrigues我想这确实有效,但它比我试图做的要复杂得多。我需要处理来自外部循环的内部循环的错误,然后在创建时再次处理错误,您也会误入不稳定的代码并受到很大的性能影响。它确实有效,但我看不出这样做比使用建筑物或建筑物然后调用它们有什么好处UnsolvedSudoku
Vec
arrayvec
std::array::from_fn
0赞
cdhowie
11/10/2023
@Pioneer_11 他只是建议对我的代码进行细微的更改,以便可以删除约束。(事实上,我只是将这个建议纳入了我的回答中。T:Copy
0赞
Pioneer_11
11/11/2023
@cdhowie我明白这一点。我确信这段代码有用途,但它没有按照我的要求进行,如果我要扩展它,那么这将是一个糟糕的解决方案。因为它需要对单个错误进行三层错误处理,而且效率低下。它是用 0 填充数组并换出值的样板。
0赞
cdhowie
11/13/2023
@Pioneer_11 在你的情况下,这与你在对你的问题的评论中提到的你很生气你不能使用它的情况几乎是一样的。所以我很困惑,因为它似乎是你喜欢的解决方案,但你同时也反对它?std::array::try_from_fn
评论
std::array::try_from_fn
在这里是理想的,但不幸的是它不稳定!
,可以隐式转换为任何类型,但几乎可以肯定它不会做你想做的事。x.expect(return Err(...))
Err
x
Err
None
return
return
WorkingCell
Default
Copy