Expected String, found &str when matching an optional string

21,830

Solution 1

This should work:

fn player_starts() -> bool {                      
    println!("Who will start me/you)");                    
    loop {
        let input = readline::readline(">");
        match input.as_ref().map(String::as_ref) {
            Some("me") => return true,
            Some("you") => return false,
            _ => ()
        }
    }
}

Note the expression in the match statement, where we convert from an Option<String> to an Option<&str>.

Solution 2

The way you usually convert a &str to a String is to_owned, e.g.

"me".to_owned()

However, you can't do pattern matching on a String. You could expect a success, get a &str from the String then pattern match on that:

fn player_starts() -> bool {                                                    
    println!("Who will start (me/you)");                                       
    loop {                                                                      
        let input = readline::readline(">");
        match input.expect("Failed to read line").as_ref() {
            "me" => return true,                                          
            "you" => return false,
            _ => println!("Enter me or you"),
        }                                                                          
    }                                                                           
}
Share:
21,830
zefciu
Author by

zefciu

Python coder from Poland.

Updated on September 11, 2020

Comments

  • zefciu
    zefciu over 3 years

    I am trying to write a simple function in Rust that will ask user a question expecting answer of "you" or "me". It should return a boolean value or ask again if the user answers wrong. I came up with:

    fn player_starts() -> bool {                                                    
        println!("Who will start (me/you)");                                       
        loop {                                                                      
            let input = readline::readline(">");                                    
            match input {                                                           
                Some("me") => return true,                                          
                Some("you") => return false,                                        
                _ => None,                                                          
            }                                                                          
        }                                                                           
    }       
    

    What I get is:

    error: mismatched types:
     expected `collections::string::String`,
        found `&'static str`
    (expected struct `collections::string::String`,
    found &-ptr) [E0308]
    

    Is there some way to coerce the literal to work here or is there some better way to achieve my goal?