简体   繁体   English

如何在 Rust 2015 中从一个模块到另一个模块进行基本的函数导入/包含?

[英]How do I do a basic import/include of a function from one module to another in Rust 2015?

I can't find how to include (or import, inject, or some other word) a function from one file (module) to another.我找不到如何将函数从一个文件(模块)包含(或导入、注入或其他词)到另一个文件(模块)。

I start a new project with我开始一个新项目

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

I modify main.rs and create a new file a.rs (inside the src dir) with the following code:我修改main.rs并使用以下代码创建一个新文件a.rs (在src目录中):

main.rs主文件

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

a.rs a.rs

pub fn foo() -> i32 { 42 }

I run the project with cargo run and get the error:我用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`

It seems that I need to import the a somehow.看来我需要以某种方式导入a I tried to add following things as a first line to main.rs我尝试将以下内容作为第一行添加到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

I have read the guide but still cannot figure out how to do imports.我已经阅读 了指南,但仍然无法弄清楚如何进行导入。

In a mainish module (main.rs, lib.rs, or subdir/mod.rs), you need to write mod a;在 mainish 模块(main.rs、lib.rs 或 subdir/mod.rs)中,您需要编写mod a; for all other modules that you want to use in your whole project (or in the subdir).对于要在整个项目(或子目录)中使用的所有其他模块。

In any other module, you need to write use a;在任何其他模块中,您需要编写use a; or use a::foo;use a::foo;

You're far from the only person to be confused by this, and it's certainly possible to do better, but any changes to the module system will get rejected as "too confusing".您远不是唯一对此感到困惑的人,当然可以做得更好,但是对模块系统的任何更改都会因为“太混乱”而被拒绝。

Edit: this answer was written for the "Rust 2015" language standard.编辑:此答案是为“Rust 2015”语言标准编写的。 Changes were made for the "Rust 2018" standard, see this blog post and the edition guide对“Rust 2018”标准进行了更改,请参阅此博客文章版本指南

In Rust, there are some keywords to deal with modules:在 Rust 中,有一些关键字来处理模块:

extern crate

extern crate fills the gap between Cargo and Rust. extern crate填补了 Cargo 和 Rust 之间的空白。 We write code in a .rs file, this file can be compiled with rustc .我们在一个 .rs 文件中编写代码,这个文件可以用rustc编译。 Cargo will manage external dependencies and call rustc . Cargo 将管理外部依赖项并调用rustc The extern crate ... line tells the compiler to look for this namespace, so it is unambiguous. extern crate ...行告诉编译器寻找这个命名空间,所以它是明确的。

Editor's noteextern crate is not required in many cases if you are using the Rust 2018 edition.编者注- 如果您使用的是 Rust 2018 版本,则在许多情况下不需要extern crate

mod

mod has two uses: mod有两个用途:

  • when used with curly braces it declares a module (namespace).当与花括号一起使用时,它声明了一个模块(命名空间)。
  • when used with just a name, it will look for the module in the local filesystem.当仅使用名称时,它将在本地文件系统中查找模块。

Modules can be:模块可以是:

  • files with extension .rs扩展名为 .rs 的文件
  • folders with one file called mod.rs包含一个名为 mod.rs 的文件的文件夹

use

use imports a namespace. use导入一个命名空间。 We are required to announce what are we going to use before using it.我们需要在使用之前宣布我们将使用什么。 The use clause is pretty strict, if we state use module1::moduleA; use 子句非常严格,如果我们声明use module1::moduleA; no other module from module1 will be available but moduleA .没有其他模块module1将可用,但moduleA An asterisk ( * ) can be used to use everything within a module: use module1::*;星号 ( * ) 可用于使用模块中的所有内容: use module1::*; . . Sets can be used as well: use module1::{moduleA, moduleB};也可以使用集合: use module1::{moduleA, moduleB};

An example:一个例子:

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

mod.rs contains: mod.rs 包含:

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

main.rs contains: 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();
}

Symbols are only usable from within the module.符号只能在模块内使用。 If you want to cross this barrier (even on a locally declared module) we need to make them public using the keyword pub .如果你想跨越这个障碍(即使是在本地声明的模块上),我们需要使用关键字pub将它们公开。

I am very late to the party, but one way to split your code into multiple files without affecting the scoping too much is the following.我参加聚会很晚,但是将代码拆分为多个文件而不会过多影响范围的一种方法如下。

Imagine a folder structure like this, for a book handling library:想象一下这样的文件夹结构,对于书籍处理库:

src/
  lib.rs
  author.rs
  book.rs

You can do:你可以做:

// lib.rs
// --------------
mod author;
use author::*;
mod book;
use book::*;

// author.rs
// --------------
struct Author {
    name: String,
    birth_year: i32,
}

// book.rs
// --------------
use super::*;

struct Book {
   title: String,
   author: Author,  // Author is in scope
   isbn: i64,
}

This structure emulates Go modules (everything in the folder seems to be in the same scope).这种结构模拟 Go 模块(文件夹中的所有内容似乎都在同一范围内)。

Another ways would be (a bit more python-style):另一种方法是(更像python风格):

// lib.rs
// --------------
mod author;
mod book;

// book.rs
// --------------
// either so, to import everything
use super::*;
// or so, one line per peer-module
use super::author;

struct Book {
   title: String,
   author: author::Author,  // Author is in scope
   isbn: i64,
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从Rust中的模块导入单个功能? - How can I import a single function from a module in Rust? 如何在模块中包含排序功能? - How do I include a sort function in a module? 如何从一个 DotNetNuke 模块重定向到另一个模块? - How do I redirect from one DotNetNuke module to another? 如何从 Rust 中的子文件夹导入函数 - How do I import functions from subfolders in Rust 如何在 Rust 货物项目中使用另一个模块中的一个模块? - How to use one module from another module in a Rust cargo project? Python - 如何将模块从另一个文件夹导入子文件夹? - Python - How do you import a module into a subfolder from another folder? 在 Rust 的同一个项目中,如何保持一个 mod 私有并在另一个模块中使用它? - How do I keep a mod private and use it in another module within the same project in Rust? 如何在TypeScript中仅导入模块的一部分? - How do I import only one part of a module in TypeScript? 如何从 python 控制台将 python 脚本作为模块导入? - How do I import a python script as a module from the python console? 我如何读取代码“from <module> 导入*“使用? - How do I read code where “from <module> import *” is used?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM