Why doesn't a & str force & String when using Vec :: contains?

A friend asked me to explain the following quirk in Rust. I could not, therefore this question:

fn main() { let l: Vec<String> = Vec::new(); //let ret = l.contains(&String::from(func())); // works let ret = l.contains(func()); // does not work println!("ret: {}", ret); } fn func() -> & 'static str { "hello" } 

Rust Playground Example

The compiler will complain as follows:

 error[E0308]: mismatched types --> src/main.rs:4:26 | 4 | let ret = l.contains(func()); // does not work | ^^^^^^ expected struct `std::string::String`, found str | = note: expected type `&std::string::String` found type `&'static str` 

In other words, &str does not force using &String .

At first I thought it was due to 'static , however it is a red herring.

The commented line captures the example due to the additional distribution.

My questions:

  • Why does &str not work with &String ?
  • Is there a way to make a call to contains without extra allocation?
+5
source share
3 answers

It seems that the Rust developers intend to tweak the contains signature to allow the above example .

In a sense, this is a known bug in contains . The fix does not seem to allow these types to be forced, but it does allow the use of the above example.

0
source

Your first question should already be @Marko's answer.

Your second question should be easy to answer, just use closure:

let ret = l.iter().any(|x| x == func());

Edit:

Not the "real" answer anymore, but I admit it here for people who may be interested in a solution for this.

+6
source

std::string::String is a growing data structure distributed over heaps, while a string slice ( str ) is an immutable string of a fixed length somewhere in memory. The string fragment is used as a borrowed type through &str . Consider this as a representation of some string date that is somewhere in memory. This is why it doesn’t make sense for str to force String , while quite the opposite makes sense. You have a heaped String somewhere in memory, and you want to use a view (line cut) for that line.

To answer the second question. There is no way to make the code work in the current form. You need to either go to the string fragment vector (so there will be no extra highlighting), or use something else and then contains .

+2
source

Source: https://habr.com/ru/post/1275579/


All Articles