Rust-reference/items/extern-crates

来自菜鸟教程
跳转至:导航、​搜索

Extern crate declarations

外部crate声明

extern-crates.md

commit: afcf00bbf22f4dec71866a8bd5f385ba1d3b70af
本章译文最后维护日期:2020-11-8

句法:

ExternCrate :
   extern crate CrateRef AsClause? ;

CrateRef :
   IDENTIFIER | self

AsClause :
   as ( IDENTIFIER | _ )

外部crate(extern crate)声明指定了对外部 crate 的依赖关系。(这种声明让)外部的 crate 作为外部crate(extern crate)声明中提供的标识符被绑定到当前声明的作用域中。as子句可用于将导入的 crate 绑定到不同的名称上。

外部crate 在编译时被解析为一个特定的 soname[1], 并且一个到此 soname 的运行时链接会传递给链接器,以便在运行时加载此 sonamesoname 在编译时解析,方法是扫描编译器的库文件路径,匹配外部crate 的 crateid。因为crateid 是在编译时通过可选的 crateid属性声明的,所以如果外部 crate 没有提供 crateid, 则默认拿该外部crate 的 name属性值来和外部crate(extern crate)声明中的[标识符]绑定。

导入 self crate 会创建到当前 crate 的绑定。在这种情况下,必须使用 as子句指定要绑定到的名称。

三种外部crate(extern crate)声明的示例:

extern crate pcre;

extern crate std; // 等同于: extern crate std as std;

extern crate std as ruststd; // 使用其他名字去链接 'std'

当给 Rust crate 命名时,不允许使用连字符(-)。然而 Cargo 包却可以使用它们。在这种情况下,当 Cargo.toml 文件中没有指定 crate 名称时, Cargo 将透明地将 - 替换为 _ 以供 Rust 源文件内的外部crate(extern crate)声明引用 (详见 RFC 940)。

这有一个示例:

// 导入 Cargo 包 hello-world
extern crate hello_world; // 连字符被替换为下划线

Extern Prelude

外部预导入包

在根模块的源码中使用外部crate(extern crate)声明或者给编译命令增加编译参数(rustc 下使用 --extern 参数选项),这两种导入外部的 crate 的方式都是把外部的 crate 导入到“外部预导入包”里。外部预导入包里的 crate 的有效作用域是整个 crate,包括内部模块。如果使用 extern crate orig_name as new_name 导入,则相应地 symbol new_name 被添加到在预导入包里。

core crate 总是会被添加到外部预导入包里。只要没有在 crate 根模块中指定应用 no_std属性,也会把 std crate 添加进来。

可以在模块上使用 no_implicit_prelude属性来禁用模块内的预导入包查找功能。

版本差异:在 2015 版中,在外部预导入包中的 crate 不能通过 use声明来直接引用,因此通常标准做法是用外部crate(extern crate)将那它们纳入到当前作用域。

从 2018 版开始, use声明可以直接引用外部预导入包里的 crate,所以再使用外部crate(extern crate)就被认为是不规范的。

注意: 随 rustc 一起引入的 crate,如 alloctest,在使用 Cargo 时不会自动被包含在 --extern 命令行参数选项中。即使在 2018 版中,也必须通过外部crate(extern crate)声明来把它们引入到当前作用域内。

extern crate alloc;
use alloc::rc::Rc;

Underscore Imports

下划线导入

外部的 crate依赖可以通过使用带有下划线形如 extern crate foo as _ 的形式来声明,而无需将其名称绑定到当前作用域内。这种声明方式对于只需要 crate 被链接进来,但 crate 从不会被当前代码引用的情况可能很有用,并且还可以避免未使用的 lint 提醒。

下划线导入不会影响 macro_use属性的正常使用,这情况下使用 macro_use属性,宏名称仍会正常导入到 macro-use预导入包中。

The no_link attribute

no_link属性

可以在外部项(extern crate item)上指定使用 no_link属性,以防止此 crate 被链接到编译输出中。这通常用于加载一个 crate 而只访问它的宏。

  1. 译者注:这里的 soname 是 linux系统里的动态库文件的 soname。