以下程序尝试对学生的分数进行评分:
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 */ })
如果向量包含 Copy
类型(如 i32
),这很好。否则这将导致无法移出借用内容错误。在这种情况下,您可能无论如何都希望使用引用。如果迭代后不再需要向量,可以使用
.into_iter()
,它使用向量并迭代拥有的项目而不是引用。[1] 移动会清除由
.drain()
方法覆盖的向量,并且复制在所有类型上都是不可能/高效的。关于vector - 为什么迭代 i32 的向量会引用 i32 (&i32)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48985903/