vector - 为什么迭代 i32 的向量会引用 i32 (&i32)?

标签 vector reference rust mapping

以下程序尝试对学生的分数进行评分:

use std::io;

fn main() {
    let mut in0 = String::new();
    io::stdin().read_line(&mut in0).expect("stdin err");
    let n: i32 = in0.trim().parse().expect("parse err");
    println!("{}", n);
    let mut v: Vec<i32> = Vec::new();
    for _ in 0..n {
        let mut inp = String::new();
        io::stdin().read_line(&mut inp).expect("stdin err");
        let num: i32 = inp.trim().parse().unwrap();
        v.push(num);
    }
    let out: Vec<_> = v
        .iter()
        .map(|x| {
            if x < 38 {
                x
            } else if x % 5 > 3 {
                x + x % 5
            } else {
                x
            }
        })
        .collect();
    println!("{:?}", v);
}

编译时出现如下错误。

error[E0308]: mismatched types
  --> src/main.rs:19:20
   |
19 |             if x < 38 {
   |                    ^^
   |                    |
   |                    expected `&i32`, found integer
   |                    help: consider borrowing here: `&38`

error[E0308]: `if` and `else` have incompatible types
  --> src/main.rs:24:17
   |
21 |               } else if x % 5 > 3 {
   |  ____________________-
22 | |                 x + x % 5
   | |                 --------- expected because of this
23 | |             } else {
24 | |                 x
   | |                 ^ expected `i32`, found `&i32`
25 | |             }
   | |_____________- `if` and `else` have incompatible types
   |
help: consider dereferencing the borrow
   |
23 |             } else *{
24 |                 x
25 |             }

x 变量如何是 &i32 类型而不是 i32 类型?

最佳答案

调用 .iter()向量上的方法返回引用向量元素的迭代器。否则,它必须将元素移动或复制出向量,这在一般情况下是不可取的 [1]。在文档中,这在声明中不是很明显:

pub fn iter(&self) -> Iter<T>  // Return type does not look like a reference

但是,示例显示您获得了引用:

assert_eq!(iterator.next(), Some(&1));  // note the `&1` instead of just `1`

可以指示闭包取消引用参数:

v.iter().map(|&x| { /* do something */ })

如果向量包含 Copyable 类型,如 i32,这很好。否则这将导致无法移出借用的内容错误。在这种情况下,您可能还是希望使用引用。

如果您在迭代后不再需要向量,您可以使用 .into_iter(),它使用向量并迭代拥有的项目而不是引用。

[1] 移动会清除 .drain() 覆盖的矢量方法,并且复制不可能在所有类型上都有效。

关于vector - 为什么迭代 i32 的向量会引用 i32 (&i32)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48985903/

相关文章:

c++ - 在 C++ 中通过引用修改此操作的开销是多少?

c# - Unity3D 删除 MonoDevelop 中的项目引用

rust - 设置 GTK 应用程序标题

for-loop - 使用 filter() 的惯用方式

rust - 从固定大小的 c_char 数组转换为 CString

c++ - 提高 std::vector 的存储容量/性能

css - 为什么有 std::vector 的迭代器

c# - 将对象的引用传递给新线程

c++:如何将数据插入结构成员(位于 vector 中的结构)

c++ - 将继承类对象的 vector 传递给需要基类 vector 的函数