参数位置中的 dyn Trait 是什么意思?

What is the meaning of a dyn Trait in argument position?

我可以在return位置看到dyn和(静态)impl特征之间的区别,例如:

fn foo() -> Box<dyn Trait> {}

fn foo() -> impl Trait {}

dyn 版本中,我可以 return 不同的类型,只要它们都实现了 Trait,而在 impl 版本中,我只允许 return 相同类型(如果我 return 引用同样适用)。

但我看不出参数位置 dyn Trait 的用途,例如:

fn foo(x: &dyn Trait) {}

fn foo(x: &impl Trait) {}  // syntatic sugar of `fn foo<T: Trait>(x: &T){}`

两者有什么区别?我为什么要使用一个或另一个? dyn 版本允许我做什么而静态版本不允许(例如,我不能通过使用 ?Sized 放宽隐式 Sized 限制来做到这一点)?

如果你熟悉C++/Java,那么dyn对应"interface reference",所以它隐含了动态多态性(因此需要一堆引用的跳转,所以它是有点慢)。

impl 是一个语法糖,为函数定义了一个模板,因此每次您将函数与另一种类型一起使用时,您将获得专门为该类型编译的函数的单独副本。所以没有额外的跳跃,但你的可执行文件会因这些副本而膨胀。 Rust 的思想告诉我们用 <T>impl 创建模板,除非编译的版本太多导致可执行文件过于臃肿。