xet*_*a11 1 inference collect rust
这段代码(游乐场):
fn resolve_score(string: String) -> u16 {
let mut score: u16;
string
.drain(..)
.map(|char| {
match char {
'a' => score += 1,
'f' => score += 4,
_ => ()
};
})
.collect();
}
Run Code Online (Sandbox Code Playgroud)
生成此错误:
<anon>:16:14: 16:21 error: unable to infer enough type information about `_`; type annotations or generic parameter binding required [E0282]
<anon>:16 .collect();
^~~~~~~
<anon>:16:14: 16:21 help: see the detailed explanation for E0282
error: aborting due to previous error
Run Code Online (Sandbox Code Playgroud)
我怎样才能解决这个问题?
您应该使用Iterator::fold而不是Iterator::collect:
fn resolve_score(string: String) -> u16 {
string.chars().fold(0, |mut score, char| {
match char {
'a' => score += 1,
'f' => score += 4,
_ => (),
}
score
})
}
Run Code Online (Sandbox Code Playgroud)
该Iterator::collect文件说:
将迭代器转换为集合.
并且Iterator::fold:
一个迭代器适配器,它应用一个函数,产生一个最终值.
在您的代码中,您有兴趣生成单个最终值(score),而不是集合,因此fold更合适.
观察:你的函数获取字符串的所有权,因此使用drain没有区别,因为字符串将被丢弃(感谢评论Matthieu M).如果你的意图是使用字符串,使其为空,但不取得所有权,你可以声明这样的函数:
fn resolve_score(string: &mut String) -> u16
Run Code Online (Sandbox Code Playgroud)
并使用drain,因此函数返回后字符串将为空.如果不需要使用该字符串,则可以接收&str参数:
fn resolve_score(string: &str) -> u16
Run Code Online (Sandbox Code Playgroud)
另请注意,collect失败是因为无法推断要生成哪个集合.你可以写:
fn resolve_score(string: String) -> u16 {
let mut score: u16 = 0;
string.chars()
.map(|char| {
match char {
'a' => score += 1,
'f' => score += 4,
_ => (),
};
})
.collect::<Vec<_>>();
score
}
Run Code Online (Sandbox Code Playgroud)
但这很奇怪,因为你不会使用结果集合(空值).