Is it possible to have a generic function on a tra

2020-04-23 07:51发布

问题:

I have:

struct Plumbus<'a> {
    grumbo: &'a Grumbo,
}

trait Grumbo {
    fn dinglebop<T>(&self, x: &mut T) -> bool { false }
}

but I get:

error[E0038]: the trait `Grumbo` cannot be made into an object
 --> plumbus.rs:4:5
  |
4 |     grumbo: &'a Grumbo,
  |     ^^^^^^^^^^^^^^^^^^ the trait `Grumbo` cannot be made into an object
  |
  = note: method `dinglebop` has generic type parameters

I want to have dinglebop do nothing by default, but depending on the Grumbo and the T, possibly fill x with a T if it makes sense for that particular Grumbo implementation.

In C++ this could probably be accomplished with partial specialization. I am not sure what to aim for with Rust.

  • Is it possible to have generic functions like this on a trait?
  • How do I accomplish my goal of having a dinglebop() for arbitrary T without specializing my Plumbus for a particular T?

回答1:

Is it possible to have a generic function on a trait?

Yes. But you are then trying to use the trait as an object. If a trait has a generic method then you can't use it as an object, but you can still use it as a bound for a type parameter.

That is, instead of using &'a Gumbo, use a T: Gumbo:

struct Plumbus<'a, T: Gumbo> { 
    grumbo: &'a T,
}

With the trait object, the implementation is only known at runtime. And its generic parameter is part of the implementation type, so the compiler couldn't know how to call it. With T: Gumbo you are putting a constraint on what T can be, but T will always be known by the compiler at the point of use, which includes any parameters of its own.

See also:

  • Understanding Traits and Object Safety
  • What makes something a "trait object"?