I'd like to have multiple versions of a function optimized for type of its arguments, and Rust call appropriate one depending on context.
In my case all arguments have the same type, and all are equivalent, so it'd rather avoid having a self
argument.
I've tried this code:
trait Foo<T> {
fn foo(a: T, b: T, c: T);
}
impl Foo<i32> {
fn foo(a: i32, b: i32, c: i32) {}
}
impl Foo<i16> {
fn foo(a: i16, b: i16, c: i16) {}
}
fn main() {
Foo::foo(1i32,2,3);
Foo::foo(1i16,2,3);
}
but Rust requires type annotations:
error: type annotations required: cannot resolve
_ : Foo<i32>
[E0283]
Can I avoid providing type annotations at the call site? If I have to, how to do it?
Remember that you always implement a trait for something. Therefore, trait implementation must always contain for
clause:
impl SomeTrait for Something
If there is no for
, then it is not a trait implementation. In your case impl Foo<i32>
is not an implementation of Foo
for i32
or whatever you think it is; it is an inherent method declaration clause on the bare trait object type Foo<i32>
.
What you actually want is possible to do using Self
type parameter:
trait Foo {
fn foo(a: Self, b: Self, c: Self);
}
impl Foo for i32 {
fn foo(a: i32, b: i32, c: i32) {}
}
impl Foo for i16 {
fn foo(a: i16, b: i16, c: i16) {}
}
fn main() {
Foo::foo(1i32,2,3);
Foo::foo(1i16,2,3);
}
This code works.
Note that now Foo
is implemented for a certain type. The type a trait is implemented for is available via the implicit Self
type parameter, and you can see how it is used in foo()
declaration.