为什么我需要声明 "extern crate core" 才能使用 libcore?

Why do I need to declare "extern crate core" to use libcore?

随着 Rust 1.6 中稳定的核心库,以下成为可能,我不再需要将 libcore 替换为 libstd

//extern crate core; //won't work without this line
extern crate num;

use core::ops::Add;
use num::bigint::{BigInt};

fn main() {
    let mut big = "8705702225074732811211966512111".parse::<BigInt>().unwrap();
    let one = "1".parse::<BigInt>().unwrap();
    big = big.add(&one);
    println!("{:?}", big);
}

但是有一件事让我很困惑——为什么我需要声明"extern crate core;"?据我所知,libstd 是建立在 libcore 之上的。 libcore 是 OS 独立的,而 libstd 的实现可以是 OS 特定的。我从来不需要指定 "extern crate std"。同样让我困惑的是,在上面的例子中,我不需要在 Cargo.toml 中添加 libcore 作为依赖项,尽管它是一个 extern crate.

只有libcore这样的情况吗?这是语言实现稳定后的暂时现象吗?

事实上,一切都非常合乎逻辑。

首先,libstd箱子确实很特别。 Rust 编译器知道它并且它隐式注入 extern crate std; 除非 #![no_std] 属性存在于板条箱根上。此外,它还会在你的板条箱的每个模块中导入标准前奏(同样,除非 #![no_std] 存在)。

现在您可能明白为什么您必须指定 extern crate core; 而同时又不需要指定 extern crate std;。您也不需要在 Cargo.toml 中指定 core 因为 libcore,以及其他几个库(libcollectionsliballocliblibc等;你可以在 Rust 编译器发行版中找到一个 up-to-date 列表 in Rust source directory)。事实上,也希望通过 Cargo 提供这些库(以 RFC 的形式表示),但截至目前,这些库仅随编译器分发提供。

最后,请记住 Rust crates 是独立的。 Rust ABI 以这种方式设计,因此您可以将同一个 crate 的不同版本构建到最终的可执行文件中。虽然一个 crate 直接依赖同一个 crate 的多个版本是无效的,但它的依赖项可以传递地依赖另一个 crate 的不同版本。这就是为什么你总是必须明确指定你的 crate 的依赖关系的原因之一:如果你没有指定你的 crate 依赖于 libcore,即使 libstd 确实依赖于 libcore , libcore 如果使用 libstd.

将不会被你的箱子自动拉动