Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trait `Borrow<String> is not implemented for `&str`

Tags:

rust

I am trying out some examples in the The Rust Programming Language book, and have the following code snippet:

fn main() {
    let mut map: HashMap<&str, i32, RandomState> = HashMap::new();
    let hello: String = String::from("hello");
    map.insert(&hello, 100);
    println!("{:?}", map); //{"hello": 100}
    let first_hello_score: Option<&i32> = map.get("hello"); // This compiles
    let hello_score: Option<&i32> = map.get(&hello); // This does not compile
}

On running cargo check, I see:

error[E0277]: the trait bound `&str: Borrow<String>` is not satisfied
  --> src/main.rs:26:27
   |
26 |     let hello_score = map.get(&hello);
   |                           ^^^ the trait `Borrow<String>` is not implemented for `&str`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.

Could someone explain why this happens?

like image 758
irrelevantUser Avatar asked Jan 03 '21 12:01

irrelevantUser


1 Answers

.get looks for &Q as the parameter, where the key type K is Borrow<Q>. Since there's a blanket implementation that borrows &T into &T, &str (the key type) can be borrowed into &str (the argument type)

However, when doing &hello, you actually have an &String, which means Rust infers String to be Q, so it tries to borrow &str into &String, which is obviously not possible. So, be explicit about the deref coercion so that Rust knows it should deref the &String into &str:

let hello_score: Option<&i32> = map.get(&hello as &str);

Or,

let hello_score: Option<&i32> = map.get(&*hello);
like image 197
Aplet123 Avatar answered Nov 19 '22 09:11

Aplet123