Они разные и служат разным целям.И то, и другое полезно, и в зависимости от обстоятельств один или другой может быть лучшим выбором.
Первый случай, &MyTrait<T>
, предпочтительно пишется &dyn MyTrait<T>
в современном Rust.Это так называемый объект черты .Ссылка указывает на любой тип, реализующий MyTrait<T>
, и вызовы методов отправляются динамически во время выполнения.Чтобы сделать это возможным, ссылка на самом деле является толстым указателем;Помимо указателя на объект он также хранит указатель на таблицу виртуальных методов типа объекта, чтобы обеспечить динамическую диспетчеризацию.Если фактический тип вашего объекта становится известным только во время выполнения, это единственная версия, которую вы можете использовать, поскольку в этом случае вам нужно использовать динамическую диспетчеризацию.Недостатком подхода является то, что существуют затраты времени выполнения, и что он работает только для черт, объектно-безопасных .
Второй случай, impl MyTrait<T>
, обозначает реализацию любого типаMyTrait<T>
еще раз, но в этом случае точный тип должен быть известен во время компиляции.Прототип
fn confirm<T>(subject: impl MyTrait<T>);
эквивалентен
fn confirm<M, T>(subject: M)
where
M: MyTrait<T>;
Для каждого типа M
, используемого в вашем коде, компилятор создает отдельную версию confim
в двоичном файле,и вызовы методов отправляются статически во время компиляции.Эта версия предпочтительна, если все типы известны во время компиляции, поскольку вам не нужно платить за динамическую диспетчеризацию конкретным типам затрат времени выполнения.
Другое отличие двух прототипов заключается в том, что первая версия принимаетsubject
по ссылке, в то время как вторая версия использует передаваемый аргумент. Однако это не является концептуальным отличием - хотя первую версию нельзя записать для использования объекта, вторую версию легко написать для принятия subject
по ссылке:
fn confirm<T>(subject: &impl MyTrait<T>);
Учитывая, что вы ввели черты для облегчения тестирования, вполне вероятно, что вы должны предпочесть &impl MyTrait<T>
.