Interface with functions that returns trait objects

Hello, I'm trying to understand the best practice for using Traits inside interfaces as return types, is this a bad practice?

The example is: I need a View trait which implements a slice function, so I can impl View for various data structures/devices.

trait View {
  // Slice the data and create another view
  fn slice(&self) -> dyn View;
}

Then I try to implement this for a CPU storage struct:

struct CPUView {}
impl View for CPUView {
  fn slice(&self) -> dyn View;
}

I got the following errors:

return type cannot have an unboxed trait object
doesn't have a size known at compile-timerustcClick for full compiler diagnostic
main.rs(25, 21): return an `impl Trait` instead of a `dyn Trait`, if all returned values are the same type: `impl `
main.rs(25, 21): box the return type, and wrap all of the returned values in `Box::new`: `Box<`, `>`, `Box::new(`, `)`

I don't really want to use box here as I don't want additional allocation. I can't use impl Trait either as return type in interface, otherwise

fn as_view() -> impl View;

Error ->
`impl Trait` only allowed in function and inherent method return types, not in `impl` method return types
see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information

Any suggestions ? Or I should just generic instead of trait here?

Depending on the use-case (&self) -> &dyn View can work.

On the other hand impl View should work in the latest Rust versions (unless you need the trait to remain object safe).

1 Like

I don't really want to return a reference there, is there any best practicing for this kinda of OOD? Like I have an interface that returns another trait object?

Thinking of how it works in Java, I guess Box<> is the closest equivalent syntax here.

Here's some alternatives and tradeoffs.

1 Like

Thanks a lot @quinedot ! First time posting here and I'm impressed with the repsonsive community! I guess associated type is the way to go, but as you posted in the playground, it earns a "parameter"...