[英]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 note —
extern 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
有两个用途:
Modules can be:模块可以是:
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.