I'm trying to add an extension method to a trait in a different crate. This trait has an associated type specified on it.
pub trait Test<W> {
type Error;
fn do_sth(&mut self) -> Result<W, Self::Error>;
}
Why is it not possible to add a method that is using the associated type Error
?
impl dyn Test<u8> {
fn use_do_sth(&mut self) -> Result<u8: Self::Error> {
self.do_sth()
}
}
playground
Nothing in Rust prevents a trait from having a method with the same name as another trait's method, nor does Rust prevent you from implementing both traits on one type. It's also possible to implement a method directly on the type with the same name as methods from traits.
Associated Types in Rust are similar to Generic Types; however, Associated Types limit the types of things a user can do, which consequently facilitates code management. Among the Generic Types of traits, types that depend on the type of trait implementation can be expressed by using the Associated Type syntax.
GATs (generic associated types) were originally proposed in RFC 1598. As said before, they allow you to define type, lifetime, or const generics on associated types. If you're familiar with languages that have "higher-kinded types", then you could call GATs type constructors on traits.
Rust is not an object oriented language. And traits are not exactly interfaces.
When you need to add a method to the external type, the only option is to use extension traits. It means that you define your own trait, with whatever methods you need, and implement it for the types you need.
When you need to add a method to all types implementing some external trait, you can use the same pattern, but instead of listing the types directly, just use the trait bound:
use std::fmt::Debug;
// This is an extension trait.
// You can force all its implementors to implement also some external trait,
// so that two trait bounds essentially collapse into one.
trait HelperTrait: Debug {
fn helper_method(&mut self);
}
// And this is the "blanket" implementation,
// covering all the types necessary.
impl<T> HelperTrait for T where T: Debug {
fn helper_method(&mut self) {
println!("{:?}", self);
}
}
Playground
The same idea could be applied to any external trait, as you wish.
Do you want the following?
impl<E> dyn Test<u8, Error = E> {
fn use_do_sth(&mut self) -> Result<u8, E> {
self.do_sth()
}
}
I came up with this following the compiler's hint that "the value of the associated type Error
must be specified".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With