Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Check if string begins with any of certain characters

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):

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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).

>Solution :

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 like this:

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 it because iter yields references to its next element, so you either need to dereference the reference, or expect it in the first place.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading