Как реализовать специализированные версии универсальной функции?
Я хотел бы иметь несколько версий функции, оптимизированной для типа ее аргументов, и Rust вызывает соответствующую в зависимости от контекста.
В моем случае все аргументы имеют один и тот же тип, и все они эквивалентны, поэтому лучше избегать self
аргумент.
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);
}
но Rust требует аннотации типа:
ошибка: требуется аннотация типа: не удается разрешить
_ : Foo<i32>
[E0283]
Могу ли я избежать предоставления аннотаций типа на сайте вызова? Если мне нужно, как это сделать?
1 ответ
Помните, что вы всегда реализуете черту чего-то. Поэтому реализация черты всегда должна содержать for
пункт:
impl SomeTrait for Something
Если нет for
, то это не черта реализации. В твоем случае impl Foo<i32>
не является реализацией Foo
за i32
или что вы думаете; это неотъемлемое условие объявления метода для простого типа объекта Foo<i32>
,
То, что вы на самом деле хотите, можно сделать, используя Self
параметр типа:
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);
}
Этот код работает.
Обратите внимание, что сейчас Foo
реализуется для определенного типа. Тип, для которого реализована черта, доступен через неявный Self
введите параметр, и вы можете увидеть, как он используется в foo()
декларация.