这种理解是否正确:特征和函数重载都实现了临时多态性,但方向不同

Ail*_*lrk 4 polymorphism typeclass rust adhoc-polymorphism

我正在学习一些多态性。

rust地址的wiki页面trait是一种实现ad hoc多态性的方法,而ad hoc多态性的页面说的function overloading是ad hoc多态性的一个例子。

根据我目前的理解水平,如果提供不同类型的参数将调用不同的实现,则函数是临时多态的。但traitfunction overloading看起来如此不同:trait对类型参数添加约束,任何类型实现都trait可以接受,而函数重载则对具体类型进行重载,任何未重载的类型都是不可接受的。

我可以说traitfunction overloading实现相反方向的临时多态性吗?是trait通过专业化还是overloading通过普遍化?

PS:在c++中,模板特化还可以根据传入的类型参数提供不同的实现,这也是ad hoc多态性的一个例子吗?

Jef*_*ett 6

实现特征涉及提供行为的实现,该行为是特定于类型的并且与其他实现分开(“临时”),并且可以在调用站点使用与其他实现相同的拼写来调用(“多态”) 。它与函数重载的方向相同。

在 C++ 中,您可以提供重载来实现临时多态性:

void foo(const X&) { ... }
void foo(const Y&) { ... }
// can call foo(z) where z is an X or a Y
Run Code Online (Sandbox Code Playgroud)

您可以对 Rust 中的特征执行相同的操作:

trait Foo { fn foo(); }
impl Foo for X { ... }
impl Foo for Y { ... }
// can call z.foo() where z is an X or a Y
Run Code Online (Sandbox Code Playgroud)

我认为您所指的“另一个方向”是能够通过类型支持的行为来限制泛型。在 Rust 中,这看起来像:

fn bar<T: Foo>(t: T) { ... }
// bar can use t.foo()
Run Code Online (Sandbox Code Playgroud)

C++有一个类比:

template<typename T> concept Foo = requires(T t) { foo(t); };
void bar(Foo auto& t) { ... }
// bar can use foo(t)
// (this uses really new C++, it's written differently in older C++)
Run Code Online (Sandbox Code Playgroud)

受约束的泛型函数不是临时多态性,因为它们有一种实现,适用于实现对其提出的任何要求的所有参数类型。

总之,特征提供了临时多态性和通用函数的约束,并且某些语言(例如 C++)使用不同的设备来实现相同的目的。C++ 中的临时多态性通常是通过函数重载来实现的。模板专业化也可以实现。