也许存在这样的疑问: rust 中的 impl Default ... / impl core::default::Default / impl ::core::default::Default 是啥区别!?


“正常情况下” 这三种写法实现的是同一个标准库 trait:core::default::Default,所以行为没有区别;区别只会在 名字解析(name resolution)避免被同名东西“遮蔽/抢名” 的时候显现出来。


1) impl Default for T

Default 是一个裸名字,它会从“当前作用域里能看到的 Default”去解析。

  • 在绝大多数 crate 里,Default 会自动从 prelude 进来(标准库预导入),所以你写 impl Default 通常就等价于实现标准库的 Default。在 std::prelude::v1 里可以看到它确实 re-export 了 core::prelude::v1::Default。 (doc.rust-lang.org)
  • 但如果你自己定义/导入了另一个同名 Default(比如 trait Default { ... },或 use xxx::Default;),那 impl Default 就会实现那个“新的 Default”,而不是标准库的。RFC 1560 也明确提到:prelude 里的名字是可以被别的名字 shadow(遮蔽)的。 (rust-lang.github.io)

一句话:impl Default 最简洁,但也最容易被同名 Default 抢走。


2) impl core::default::Default for T

这是一个路径,第一段是 core

  • Rust Reference 说明:core 这个 crate 永远在 extern prelude 里,所以一般情况下 core::... 能直接用。 (doc.rust-lang.org)
  • 但这里仍然有个“坑”:如果你在当前模块/作用域里刚好也有个叫 core 的模块/导入别名,那 core::default::Default 可能会解析到你自己的 core,而不是真正的 core crate。

一句话:比裸 Default 更明确,但 core 这个名字本身仍可能被本地同名项遮蔽。


3) impl ::core::default::Default for T

开头的 ::Rust 2018+(包括 2021/2024)有特殊含义:

:: 开头的路径从 extern prelude 解析,并且后面必须跟一个 crate 名。 (doc.rust-lang.org)

core 又是“永远在 extern prelude 里”的那个 crate。 (doc.rust-lang.org)

所以 ::core::default::Default 是三者里最“指名道姓”、最不怕抢名/遮蔽的一种。(这也是很多宏展开/生成代码喜欢用的写法:稳。)


什么时候会真的不一样?两个典型例子

A) Default 被你自己定义/导入的同名 trait 抢走

trait Default { fn default() -> Self; } // 你自己的
struct S;

impl Default for S {
    fn default() -> Self { S }
}
// 这里实现的是“你自己的 Default”,不是标准库的。

B) core 这个名字被本地模块抢走

mod core { pub mod default { pub trait Default {} } } // 本地 core
struct S;

impl core::default::Default for S {}  // 指向“本地 core”
impl ::core::default::Default for S { // 指向“真正的 core crate”
    fn default() -> Self { S }
}

实用建议(按“稳健程度”排序)

  • 写业务代码:impl Default for T(最常见、最干净)。 (doc.rust-lang.org)
  • 写库/宏/生成代码、或者你就是讨厌命名歧义:impl ::core::default::Default for T(最稳)。 (doc.rust-lang.org)
  • no_std 场景:用 core 很合理;no_std 会把标准 prelude 切换到 core prelude。 (doc.rust-lang.org)

宇宙就是这么爱玩“同名抢椅子”游戏:想省心就把椅子编号(::core::...),想简洁就直接喊名字(Default)。