Hi there.
As title, how can I write a function that accepts both Box<dyn Foo> and &Box<dyn Foo>?
More specifically, in my case, I would like to get a function that accepts Vec<Box<dyn Foo>> and Vec<&Box<dyn Foo>>.
I thought both implemented Foo, so function like the following should work fine:
fn accept_foos<T: Foo>(foos: Vec<T>) {
// some operations...
}
but actually this wouldn't work at all. The error message I got:
error[E0277]: the trait bound `Box<dyn Foo>: Foo` is not satisfied
--> src/main.rs:20:17
|
5 | fn accept_foos<T: Foo>(foos: Vec<T>) {
| --- required by this bound in `accept_foos`
...
20 | accept_foos(foos1);
| ^^^^^ the trait `Foo` is not implemented for `Box<dyn Foo>`
error[E0277]: the trait bound `&Box<dyn Foo>: Foo` is not satisfied
--> src/main.rs:21:17
|
5 | fn accept_foos<T: Foo>(foos: Vec<T>) {
| --- required by this bound in `accept_foos`
...
21 | accept_foos(foos2);
| ^^^^^ the trait `Foo` is not implemented for `&Box<dyn Foo>`
Thanks for the quick reply!
So if Foo is defined in an external crate I don't have control over, is there no way to write a function I want?
I gave a generic function as an example because this was what I tried, but I'm not particular about how it is achieved. That is, I can do something on the caller side rather than the callee side (i.e. function definition).
fn accept_foos<T: AsRef<dyn Foo>>(foos: Vec<T>) {
// some operations
for foo in foos {
let _a_foo: &dyn Foo = foo.as_ref(); // getting a `dyn Foo` from `T``
}
}
The advantage of @2e71828 solution is that it also works for &dyn Foo for my version you would need to
implement AsRef<dyn Foo> for &dyn Foo which you can't do if Foo is from a external crate.