Reputation: 323
So I just started learning about Rust and the Implicit Deref Coercion. A "problem" I now often tumble over, is that this automatic deref does not work inside of other types, e.g. as Item types of collections. In the following example (sandbox), what changes can be done in the function signature, to make the last line in main
work, or is there no other way than do the conversion outside of the function call explicitly?
fn find_in_vec<T>(v: Vec<T>) -> bool
where
T: AsRef<str>
{
for e in v {
if e.as_ref() == "hello" {
return true;
}
}
false
}
fn is_hello(s: &str) -> bool {
s == "hello"
}
fn main() {
let h1: &str = "hello";
let h2: &String = &"hi".to_string();
let h3: &Box<String> = &Box::new("hi".to_string());
println!("{}", is_hello(h1)); // works
println!("{}", is_hello(h2)); // works
println!("{}", is_hello(h3)); // works
let a: Vec<&str> = vec!["hello", "world", "!"];
let b: Vec<&str> = vec!["hallo", "world", "!"];
let chelp = "hello".to_string();
let c: Vec<&String> = vec![&chelp];
let d: Vec<&Box<String>> = vec![&Box::new("hello".to_string())];
println!("{}", find_in_vec(a)); // works
println!("{}", find_in_vec(b)); // works
println!("{}", find_in_vec(c)); // works
println!("{}", find_in_vec(d)); // fails
}
Compile Error:
error[E0277]: the trait bound `Box<String>: AsRef<str>` is not satisfied
--> src/main.rs:33:32
|
33 | println!("{}", find_in_vec(d));
| ----------- ^ the trait `AsRef<str>` is not implemented for `Box<String>`
| |
| required by a bound introduced by this call
|
= help: the trait `AsRef<T>` is implemented for `Box<T, A>`
= note: required for `&Box<String>` to implement `AsRef<str>`
note: required by a bound in `find_in_vec`
Any insights on idiomatic ways to solve/work around/avoid this problem would be greatly appreciated!
Note: I know that the Box<String>
is overkill in this example, just consider it a minimal example. In my "real" world, I don't have boxed Strings but a list of pointers to different structs all having the same Trait, e.g. Box<dyn MyTrait>
.
Upvotes: 0
Views: 64