rust 类型限定之路径导入限定
也许存在这样的疑问: 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,而不是真正的corecrate。
一句话:比裸 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 切换到coreprelude。 (doc.rust-lang.org)
宇宙就是这么爱玩“同名抢椅子”游戏:想省心就把椅子编号(::core::...),想简洁就直接喊名字(Default)。
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Unic
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果