迭代器reduce中无法返回对临时值错误的引用

s1n*_*7ax 0 rust

我正在尝试使用减速器计算元素总数。

// map: Map<(i8, i8), u8>
// row: Vec<u8>

row.push(
    *map
    .values()
    .reduce(|acc, curr| &(acc + curr))
    .unwrap_or(&0u8)
);
Run Code Online (Sandbox Code Playgroud)

我收到以下编译错误。

error[E0515]: cannot return reference to temporary value
   --> src/main.rs:173:46
    |
173 |                         .reduce(|acc, curr| &(acc + curr))
    |                                              ^-------------
    |                                              ||
    |                                              |temporary value created here
    |                                              returns a reference to data owned by the current function
Run Code Online (Sandbox Code Playgroud)

这里,reduce是期望值&u8,但不能更改为引用,因为它是临时值。如何解决这个问题?

Den*_*ret 5

一个通用的解决方案是将元素从引用映射到具体值,这在这里是可能的并且便宜:

row.push(
    map
        .values()
        .copied() // shortcut for .map(|&v| v)
        .reduce(|acc, curr| (acc + curr))
        .unwrap_or(0)
);
Run Code Online (Sandbox Code Playgroud)

但更干净的解决方案是避免reduce,它会根据接收到的元素类型构建结果,但使用fold

row.push(
    map
        .values()
        .fold(0, |acc, &curr| (acc + curr))
);
Run Code Online (Sandbox Code Playgroud)

这还可以让您避免unwrap_or在地图为空时使用初始值。

到目前为止,我一直假设您的计算比您所展示的更复杂。如果不是这种情况,那么只需使用sum

row.push(map.values().sum());
Run Code Online (Sandbox Code Playgroud)

  • 值得注意的是,`map(|&amp;v| v)` 已经在 std 中作为 [`Iterator::copied()`](https://doc.rust-lang.org/stable/std/iter/trait .Iterator.html#method.复制)。 (2认同)