试图耗尽一个字符串并映射到它的字符上,但由于类型推断而失败
Trying to drain a string and map on its chars but failing because of type inference
此代码(Playground):
fn resolve_score(string: String) -> u16 {
let mut score: u16;
string
.drain(..)
.map(|char| {
match char {
'a' => score += 1,
'f' => score += 4,
_ => ()
};
})
.collect();
}
生成此错误:
<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
我该如何解决这个问题?
你应该使用 Iterator::fold
instead of Iterator::collect
:
fn resolve_score(string: String) -> u16 {
string.chars().fold(0, |mut score, char| {
match char {
'a' => score += 1,
'f' => score += 4,
_ => (),
}
score
})
}
Iterator::collect
文档说:
Transforms an iterator into a collection.
和Iterator::fold
:
An iterator adaptor that applies a function, producing a single, final value.
在您的代码中,您有兴趣生成单个最终值 (score
),而不是一个集合,因此 fold
更合适。
观察结果:您的函数拥有字符串的所有权,因此使用 drain
没有任何区别,因为无论如何都会删除该字符串(感谢评论 Matthieu M).如果您打算使用字符串,使其为空,但不获取所有权,则可以这样声明函数:
fn resolve_score(string: &mut String) -> u16
并使用drain
,所以字符串在函数returns之后为空。如果不需要消费字符串,可以接收一个&str
参数:
fn resolve_score(string: &str) -> u16
另请注意,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
}
但这会很奇怪,因为您不会使用结果集合(空值)。
此代码(Playground):
fn resolve_score(string: String) -> u16 {
let mut score: u16;
string
.drain(..)
.map(|char| {
match char {
'a' => score += 1,
'f' => score += 4,
_ => ()
};
})
.collect();
}
生成此错误:
<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
我该如何解决这个问题?
你应该使用 Iterator::fold
instead of Iterator::collect
:
fn resolve_score(string: String) -> u16 {
string.chars().fold(0, |mut score, char| {
match char {
'a' => score += 1,
'f' => score += 4,
_ => (),
}
score
})
}
Iterator::collect
文档说:
Transforms an iterator into a collection.
和Iterator::fold
:
An iterator adaptor that applies a function, producing a single, final value.
在您的代码中,您有兴趣生成单个最终值 (score
),而不是一个集合,因此 fold
更合适。
观察结果:您的函数拥有字符串的所有权,因此使用 drain
没有任何区别,因为无论如何都会删除该字符串(感谢评论 Matthieu M).如果您打算使用字符串,使其为空,但不获取所有权,则可以这样声明函数:
fn resolve_score(string: &mut String) -> u16
并使用drain
,所以字符串在函数returns之后为空。如果不需要消费字符串,可以接收一个&str
参数:
fn resolve_score(string: &str) -> u16
另请注意,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
}
但这会很奇怪,因为您不会使用结果集合(空值)。