Please check the P.S. part for more details.
Let's say we have a trait like this:
trait Foo {
type MyType;
fn test(&self, v: &Self::MyType);
}
and in my case, the v
parameter will not be used for most types, in other words, most implementation of Foo will act the same no matter what type of MyType
is:
impl Foo for char {
type MyType = ??? ;
fn test(&self, _v: &Self::MyType) {
println!("hello");
}
}
So I modify my code like this:
struct MyTypeImpl {
id: usize,
}
trait Foo<T> {
type MyType;
fn test(&self, v: &Self::MyType);
}
impl<T> Foo<T> for u32 {
type MyType = MyTypeImpl;
fn test(&self, v: &Self::MyType) {
println!("hello my type {}", v.id)
}
}
impl<T> Foo<T> for char {
type MyType = T;
fn test(&self, _v: &Self::MyType) {
println!("hello");
}
}
fn main() {
test_fn::<MyTypeImpl>();
}
fn test_fn<T>() {
let t1 = MyTypeImpl { id: 1 };
let i: u32 = 1;
i.test(&t1);
let c: char = 'c';
c.test(&t1);
}
but this code will not compile:
error[E0282]: type annotations needed
--> src/main.rs:33:7
|
33 | i.test(&t1);
| ^^^^ cannot infer type for type parameter `T`
So is there any way I can just ignore the associated type? Will the new feature GATs do this?
P.S. Only codes seems not clarify what I met and what I want, here are more details:
I have a serialization crate, which declare a trait that will decode bytes into certain types:
pub trait DeSerialization: + Sized {
fn decode(ptr: &mut *const u8, ctx: &DecodeContext) -> Result<Self, DecodeError>;
}
And I have implemented a lot of basic and common types, so there's no need to let user implement them by themselves, all of these types do not need ctx
to decode byte streams.
But there are some cases users want to manually implement a type, usually a custom struct. The DecodeContext
save some other information, for types cannot be decoded just by bytes (this is weird, but I won't explain here, that' too complicated and have nothing to do with this question).
But I found that the DecodeContext
I defined will never meet all the requirements, so I want to let user define it, that why I want to use an associated type:
pub trait DeSerialization: + Sized {
type DecodeContext;
fn decode(ptr: &mut *const u8, ctx: &Self::DecodeContext) -> Result<Self, DecodeError>;
}
Then it turns to the problem I asked, remember that I implemented a lot of basic or common types before, if I change the trait, all the implementations will need a type, too. Since all these trait implements are pre-defined by me, the associated type must not be a certain type, but somehow to be generic.
The Marcos will help here, but that's the last way I want to go.
Another way is to give up associated types, while pass a pointer, than cast it to the type user defines, that also a way I don't want, I'm trying to avoid using unsafe code as much as possible.