最近我看到不同的地方给出了示例代码,并在我的编辑器中编写它,它似乎是有效的代码。
trait Trait {}
impl<T> Trait for T {}
我似乎找不到任何解释这一点的文档;我确信它存在,但我真的不知道该谷歌什么。
如何实例化
T
然后调用 impl 块中的任何方法?
我确信这是有充分理由的,但我似乎无法理解它,有人能够在 Rust 中链接此功能的相关文档吗?
编辑
从答案中我意识到我可能还不清楚,我已经复制了我所看到的示例。
虽然从第一个答案中,我意识到下面的代码也是有效的,也许更清楚地表达了我想要问的问题,即允许此代码有效的泛型语法有什么用:
trait Trait {
fn test() -> String {
"test".to_string()
}
}
impl<T: Default> Trait for T {}
这是否会影响文件中现有的结构和枚举,或者它实际上什么都不做,并且永远不能被调用或使用?
此代码向您展示了两件事:标记特征和总体实现。
trait Foo {}
(没有特征成员)声明一个标记特征,它仅用于标记某些类型。内置性状 Copy
、Send
和 Sync
是标记性状的良好示例。
impl<T> Foo for T {}
为所有类型实现特征 Foo
,即所谓的 blanket 实现。
总的来说,这几乎是多余的,因为“实现
Foo
的类型”和“所有类型”之间没有区别。
然而,看似无用的一揽子实施实际上在实践中很有用。在 Rust 标准库中,有一个全面的实现
impl<T> From<T> for T
,它告诉 Rust“你可以将任何 T
转换为 T
”。这本身并没有什么用处,但最终在通用代码中很有用,例如 fn foo(arg: impl Into<i32>)
,它允许您传递可以无误地转换为 i32
的任何类型的参数。 由于全面实施,这包括 i32
本身。
如何实例化
然后调用 impl 块中的任何方法?T
嗯,在这种情况下,
impl
块的主体不能有任何东西。 impl ... for
块的主体是实现特征成员,但正在实现的特征没有成员。
如果我们假设特征确实有成员,那么你的问题的答案就是你必须以一种允许你对其执行操作的方式绑定
T
。例如,要创建 T
,您可以选择添加绑定 T: Default
,这将允许您调用 T::default()
来创建具有(类型定义的)默认值的 T
实例。
请注意,在
T
上添加边界将更改实现的范围,使其仅适用于满足边界的类型。这在实践中很常见。例如,Clone
在Vec<T>
上的实现以T: Clone
为界。 (毕竟,如果您无法克隆矢量的元素,您将如何克隆矢量?)
进一步阅读: