I want to check if a string begins with a vowel. While I could iterate over a list of vowels and check each individually like so:
let s = String::from("apple");
let vowels = ['a', 'e', 'i', 'o', 'u'];
for v in vowels {
if s.starts_with(v) {
println!("{} starts with a vowel.", s);
break;
}
}
I'd prefer a better / more concise way. Here is what I tried:
if vowels.iter().any(|v| s.starts_with(v)) {
println!("{} begins with a vowel.", s);
}
This gives the following error(s):
error[E0277]: expected a `Fn<(char,)>` closure, found `char`
--> src/exercises.rs:61:44
|
61 | if vowels.iter().any(|v| s.starts_with(v)) {
| ----------- ^ expected an `Fn<(char,)>` closure, found `char`
| |
| required by a bound introduced by this call
|
= help: the trait `Fn<(char,)>` is not implemented for `char`
= note: required because of the requirements on the impl of `FnOnce<(char,)>` for `&char`
= note: required because of the requirements on the impl of `Pattern<'_>` for `&char`
note: required by a bound in `core::str::<impl str>::starts_with`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `ch8_common_collections` due to previous error
I'm not sure how to do this. I just want to determine if the string begins with a vowel. Yes, I know this is an English/ASCII-centric solution (I'm a beginner).
CodePudding user response:
That isn't a great error message, but you just need to take a reference in your closure:
fn main() {
let s = String::from("apple");
let vowels = ['a', 'e', 'i', 'o', 'u'];
if vowels.iter().any(|&v| s.starts_with(v)) {
// ^
println!("{} begins with a vowel.", s);
}
}
or deref v
:
fn main() {
let s = String::from("apple");
let vowels = ['a', 'e', 'i', 'o', 'u'];
if vowels.iter().any(|v| s.starts_with(*v)) {
// ^
println!("{} begins with a vowel.", s);
}
}
The reason for that is because iter
yields references to its next element, so you either need to dereference the reference, or expect it in the first place.