2015-12-26 6 views
3

Я хотел бы иметь несколько версий функции, оптимизированной для типа ее аргументов, и Rust называть подходящую в зависимости от контекста.Как реализовать специализированные версии общей функции?

В моем случае все аргументы имеют один и тот же тип, и все они эквивалентны, поэтому лучше избегать аргумента self.

Я 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); 
} 

но Rust требует аннотации типов:

error: type annotations required: cannot resolve _ : Foo<i32> [E0283]

Могу ли я избегать предоставления аннотацию типа на месте вызова? Если мне нужно, как это сделать?

+1

Любая текущая специализация общей функции - это причуда, которая, вероятно, на самом деле не предназначена для работы (т. Е. Это ошибка). [Истинная специализация] (https://github.com/rust-lang/rfcs/pull/1210) - это предлагаемая, но не реализованная функция. – huon

+0

@huon: Разве это не ответ, как временный? –

ответ

10

Помните, что вам всегда осуществить черту для что-то. Таким образом, реализация черта должна всегда содержат 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); 
} 

Этот код works.

Обратите внимание, что в настоящее время введен Fooдля определенного типа. Тип, для которого реализован признак, доступен через неявный параметр типа Self, и вы можете видеть, как он используется в объявлении foo().