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

Module 如何在Rust 2015中从一个模块向另一个模块基本导入/包含功能?,module,rust,Module,Rust,我找不到如何将函数从一个文件(模块)包含到另一个文件(模块)中(或导入、注入或其他单词) 我开始了一个新的项目 $cd~/项目 $cargo新项目——bin $cd项目 $tree . | --货舱 --src | --梅因 我用以下代码修改main.rs,并创建一个新文件a.rs(在srcdir中): main.rs fn main() { println!("{}", a::foo()); } pub fn foo() -> i32 { 42 } a.rs fn main

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

我开始了一个新的项目

$cd~/项目
$cargo新项目——bin
$cd项目
$tree
.
|
--货舱
--src
|
--梅因
我用以下代码修改
main.rs
,并创建一个新文件
a.rs
(在
src
dir中):

main.rs

fn main() {
    println!("{}", a::foo());
}
pub fn foo() -> i32 { 42 }
a.rs

fn main() {
    println!("{}", a::foo());
}
pub fn foo() -> i32 { 42 }
我使用
cargo run
运行项目,并得到错误:

错误[E0433]:未能解决:使用未声明的类型或模块`a`
-->src/main.rs:2:20
|
2 | println!(“{}”,a::foo());
|^a未声明的类型或模块的使用`
似乎我需要以某种方式导入
a
。我尝试将以下内容作为第一行添加到
main.rs

  • 使用密码

    错误[E0432]:未解析的导入`a`
    -->src/main.rs:1:5
    |
    1 |使用一个;
    |^根中没有'a'
    
  • 使用a::*

    错误[E0432]:未解析的导入`a`
    -->src/main.rs:1:5
    |
    1 |使用a::*;
    |^可能是丢失的“外部板条箱a;”?
    错误[E0433]:未能解决:使用未声明的类型或模块`a`
    -->src/main.rs:4:20
    |
    4 | println!(“{}”,a::foo());
    |^a未声明的类型或模块的使用`
    
  • 使用a::foo

    错误[E0432]:未解析的导入`a`
    -->src/main.rs:1:5
    |
    1 |使用a::foo;
    |^可能是丢失的“外部板条箱a;”?
    错误[E0433]:未能解决:使用未声明的类型或模块`a`
    -->src/main.rs:4:20
    |
    4 | println!(“{}”,a::foo());
    |^a未声明的类型或模块的使用`
    
  • 外部板条箱a;使用a::foo

    错误[E0463]:找不到'a'的板条箱`
    -->src/main.rs:1:1
    |
    1 |外部板条箱a;
    |^^^^^^^^^^^^^^^^^^^^找不到板条箱
    
  • 外部板条箱项目;使用proj::a::foo

    错误[E0463]:找不到'proj'的板条箱`
    -->src/main.rs:1:1
    |
    1 |外部板条箱项目;
    |^^^^^^^^^^^^^^^^^^^^^^^^^找不到板条箱
    
我已经读过,但仍然不知道如何进行导入。

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

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

你不是唯一一个对此感到困惑的人,当然也有可能做得更好,但对模块系统的任何更改都会被拒绝,因为“太困惑”


编辑:此答案是为“Rust 2015”语言标准编写的。对“Rust 2018”标准进行了更改,请参见和Rust中的

,其中有一些关键词用于处理模块:

extern板条箱
外部板条箱
填补了货物与铁锈之间的空隙。我们在一个.rs文件中编写代码,这个文件可以用
rustc
编译。Cargo将管理外部依赖项并调用
rustc
extern板条箱…
行告诉编译器查找这个名称空间,因此它是明确的

编者注-
如果您使用的是Rust 2018版本,则在许多情况下不需要外部板条箱

mod
mod
有两种用途:

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

  • 扩展名为.rs的文件
  • 包含一个名为mod.rs的文件的文件夹
使用
use
导入命名空间。我们需要在使用它之前宣布我们将使用什么。如果我们声明
use module1::moduleA,那么use子句非常严格模块1
中没有其他模块可用,但模块a
中的模块可用。星号(
*
)可用于使用模块内的所有内容:
使用模块1::*。也可以使用集合:
use module1::{moduleA,moduleB}

例如:

| main.rs
|-模块1
|-国防部
|-模数
|-模块B.rs
mod.rs包含:

pub mod moduleA; // declare a child module
pub mod moduleB; // declare a child module
///  ======
// 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();
}
main.rs包含:

pub mod moduleA; // declare a child module
pub mod moduleB; // declare a child module
///  ======
// 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

来公开这些障碍,但有一种方法可以将代码拆分为多个文件,而不会对范围造成太大影响

想象一下这样的文件夹结构,对于图书处理库:

src/
  lib.rs
  author.rs
  book.rs
你可以做:

//lib.rs
// --------------
作者;
使用作者::*;
修改书;
使用手册::*;
//作者
// --------------
结构作者{
名称:String,
出生年份:i32,
}
//书刊
// --------------
使用超级::*;
结构书{
标题:字符串,
作者:作者,//作者在范围内
isbn:i64,
}
此结构模拟Go模块(文件夹中的所有内容似乎都在同一范围内)

另一种方法是(更具python风格):

//lib.rs
// --------------
作者;
修改书;
//书刊
// --------------
//要么如此,要么导入所有内容
使用超级::*;
//大约,每个对等模块一行
使用super::author;
结构书{
标题:字符串,
author:author::author,//author在范围内
isbn:i64,
}

那么什么时候需要外部板条箱呢?我原以为每个Rust文件都是一个单独的板条箱(编译单元)。@voithos你的main.rs或lib.rs,它通过
mod
指令递归反转的所有文件都将编译为一个板条箱。这是编译单元。
但是对模块系统的任何更改都将得到rejec