这是什么:`impl<T> Trait for T {}`?

Ste*_*cou 2 traits rust

最近,我看到不同的地方将其作为示例代码给出,并在我的编辑器中编写它,它似乎是有效的代码。

\n
trait Trait {}\n\nimpl<T> Trait for T {}\n
Run Code Online (Sandbox Code Playgroud)\n

我似乎找不到任何解释这一点的文档;我确信它存在,但我真的不知道该用谷歌搜索什么。

\n

您将如何实例化T并调用 impl 块中的任何方法?

\n

我确信这是有充分理由的,但我似乎无法理解它,有人能够在 Rust 中链接此功能的相关文档吗?

\n
\n

从回答中我意识到我可能没有说清楚;我从我所看到的\xe2\x80\x99 中复制了示例。

\n

虽然从第一个答案中,我意识到下面的代码也是有效的,也许更清楚地表达了我\xe2\x80\x99m试图问的问题,即允许此代码的泛型语法有什么用有效:

\n
trait Trait {\n    fn test() -> String {\n        "test".to_string()\n    }\n}\n\nimpl<T> Trait for T {}\n
Run Code Online (Sandbox Code Playgroud)\n

这是否会影响文件中现有的结构和枚举,或者它实际上什么都不做,并且永远不能被调用或使用?

\n

cdh*_*wie 7

此代码向您展示了两件事:标记特征和总体实现。

trait Foo {}(没有特征成员)声明一个标记特征,仅用于标记某些类型。内置特征CopySend、 和Sync是标记特征的好例子。

impl<T> Foo for T {}为所有类型实现该特征Foo,即所谓的一揽子实现。

总的来说,这几乎是多余的,因为“实现的类型”和“所有类型”之间没有区别Foo

然而,看似无用的一揽子实现实际上在实践中很有用。在 Rust 标准库中,有一个全面的实现impl<T> From<T> for T,它告诉 Rust“你可以将任何内容转换TT.” 这本身并没有什么用处,但最终在通用代码中很有用,例如fn foo(arg: impl Into<i32>)它可以让您传递可以无误地转换为 的任何类型的参数i32由于全面实施,这包括i32其自身。

您将如何实例化T然后调用 impl 块中的任何方法?

好吧,在这种情况下,块体impl不能有任何东西。块的主体impl ... for是实现特征成员,但正在实现的特征没有成员。

如果我们假设该特征确实成员,那么您问题的答案将是您必须以T一种允许您对其执行操作的方式进行绑定。例如,要创建 ,T您可以选择添加绑定T: Default,这将允许您调用创建具有(类型定义的)默认值T::default()的实例。T

请注意,添加界限T会将实现的范围更改为仅适用于满足界限的类型。这在实践中很常见。例如,Cloneon的实现Vec<T>以 为界T: Clone。(毕竟,如果你无法克隆它的元素,你将如何克隆一个向量?)


进一步阅读: