如何在Rust 2015中从一个模块到另一个模块执行基本导入/包含功能?

问题描述 投票:39回答:2

我找不到如何将函数从一个文件(模块)包含(或导入,注入或其他一些单词)到另一个文件。

我开始一个新项目

$ cd ~/projects
$ cargo new proj --bin
$ cd proj
$ tree
.
|
-- Cargo.toml
-- src
   |
   -- main.rs

我修改main.rs并使用以下代码创建一个新文件a.rs(在src目录内):

卖弄.人生

fn main() {
    println!("{}", a::foo());
}

啊.人生

pub fn foo() -> i32 { 42 }

我用cargo run运行项目并得到错误:

error[E0433]: failed to resolve: use of undeclared type or module `a`
 --> src/main.rs:2:20
  |
2 |     println!("{}", a::foo());
  |                    ^ use of undeclared type or module `a`

似乎我需要以某种方式导入a。我尝试将以下内容添加为main.rs的第一行

  • use a; error[E0432]: unresolved import `a` --> src/main.rs:1:5 | 1 | use a; | ^ no `a` in the root
  • use a::*; error[E0432]: unresolved import `a` --> src/main.rs:1:5 | 1 | use a::*; | ^ maybe a missing `extern crate a;`? error[E0433]: failed to resolve: use of undeclared type or module `a` --> src/main.rs:4:20 | 4 | println!("{}", a::foo()); | ^ use of undeclared type or module `a`
  • use a::foo; error[E0432]: unresolved import `a` --> src/main.rs:1:5 | 1 | use a::foo; | ^ maybe a missing `extern crate a;`? error[E0433]: failed to resolve: use of undeclared type or module `a` --> src/main.rs:4:20 | 4 | println!("{}", a::foo()); | ^ use of undeclared type or module `a`
  • extern crate a; use a::foo; error[E0463]: can't find crate for `a` --> src/main.rs:1:1 | 1 | extern crate a; | ^^^^^^^^^^^^^^^ can't find crate
  • extern crate proj; use proj::a::foo; error[E0463]: can't find crate for `proj` --> src/main.rs:1:1 | 1 | extern crate proj; | ^^^^^^^^^^^^^^^^^^ can't find crate

我读过the guide但仍然无法弄清楚如何进口。

module rust
2个回答
38
投票

在mainish模块(main.rs,lib.rs或subdir / mod.rs)中,您需要为要在整个项目(或子目录)中使用的所有其他模块编写mod a;

在任何其他模块中,您需要编写use a;use a::foo;

你不是唯一一个被这个混淆的人,并且它当然可以做得更好,但对模块系统的任何改变都会被拒绝为“太混乱”。

编辑:这个答案是为“Rust 2015”语言标准编写的。对“Rust 2018”标准进行了更改,请参阅this blog postedition guide


14
投票

在Rust中,有一些关键字可以处理模块:

extern crate

extern crate填补了Cargo和Rust之间的空白。我们在.rs文件中编写代码,这个文件可以用rustc编译。 Cargo将管理外部依赖项并调用rustcextern crate ...行告诉编译器查找这个命名空间,因此它是明确的。

编者注 - 如果您使用的是Rust 2018版本,在许多情况下不需要extern crate

mod

mod有两个用途:

  • 当与花括号一起使用时,它声明一个模块(命名空间)。
  • 当只使用名称时,它将在本地文件系统中查找模块。

模块可以是:

  • 扩展名为.rs的文件
  • 一个名为mod.rs的文件夹

use

use导入名称空间。我们需要在使用之前宣布我们将要使用的内容。 use子句是非常严格的,如果我们陈述use module1::moduleA;没有来自module1的其他模块将可用但是moduleA。星号(*)可用于使用模块中的所有内容:use module1::*;。集合也可以使用:use module1::{moduleA, moduleB};

一个例子:

| main.rs
|- module1
      |- mod.rs
      |- moduleA.rs
      |- moduleB.rs

mod.rs包含:

pub mod moduleA; // declare a child module
pub mod moduleB; // declare a child module

main.rs包含:

///  ======
// use what Cargo downloaded
extern crate that_one_thing_i_need;

///  ======

mod module1; // declare a child module

// some local stuff I want to scope
mod local {
    pub fn my_function() {}
}

//   ======

// make the symbols locally available:
use module1::moduleA::*;
use module1::moduleB::{functionX, moduleY, typeZ};

// we still need to announce what stuff from the external crate
// we want to use:
// We can do local aliases that will be valid in this one file.
use that_one_thing_i_need::fancy_stuff as fs;

///  ======

fn main() {
    // we can use anything here from the namespaces we are using:
    //      moduleA
    //      functionX
    //      moduleY
    //      typeZ
    //      fs

    // We can access stuff by navigating from the outermost visible
    // module name
    local::my_function();
}

符号仅可在模块内使用。如果你想跨越这个障碍(甚至在本地声明的模块上),我们需要使用关键字pub将它们公开。

© www.soinside.com 2019 - 2024. All rights reserved.