Rust基础学习-ModulesPackage

server/2024/10/18 12:22:38/

在Rust中,模块有助于将程序分割成逻辑单元,以提高可读性和组织性。一旦程序变得更大,将其拆分为多个文件或命名空间非常重要。

模块有助于构建我们的程序。模块是项目的集合:包括函数、结构体甚至其他模块。

cargo


Module

定义模块

Rust中,可以使用mod关键字来定义一个模块,语法如下:

rust">mod module_name {// code
}

这里,module_name 是模块的名称。看下面的例子;

rust">mod config {fn print() {println!("config!");}
}

上面的示例中,我们使用mod定义了以config为名称的一个模块。在模块内部,我们定义 了一个简单的函数print;


Rust 模块内项目的可见性

模块中的项目可以是私有的或公共的。默认情况下,模块是私有的。

这意味着模块内部的项目无法在模块外部访问。pub 关键字可用于使项目具有公共可见性。让我们看一个示例。

rust">mod config {// items in modules by default have private visibilityfn select() {println!("called config::select");}// use the `pub` keyword to override private visibilitypub fn print() {println!("called config::print");}
}

在这里,我们定义一个名为config的模块,其中包含两个函数select()print()

print()函数以pub关键字开头,这意味着它具有公共可见性。但select()函数则没有。

如果你此时运行程序会发现有一些警告,这是因为我们并没有调用这些函数,现在,我们尝试调用一下;

rust">mod config {// items in modules by default have private visibilityfn select() {println!("called config::select");}// use the `pub` keyword to override private visibilitypub fn print() {println!("called config::print");}
}fn main() {// public items inside module can be accessed outside the parent module// call public print function from display moduleconfig::print();
}

在这里,我们使用config::print()语法来调用 config 模块内的公共函数 print():: 运算符用于分隔模块名称和要在模块内调用的项目。

但是,模块内部的私有项目不可在模块外部访问。如果我们尝试在 config 模块内调用私有函数 select(),将会收到编译错误。


注意:当在模块内部某个用pub修饰的方法调用模块内部非pub方法时,我们在调用该pub方法时,其涉及到的非pub方法也将具有pub性质;

我们看个例子:

rust">mod player {// private functionfn focus() {println!("called player::focus");}// public functionpub fn shift() {println!("called player::shift");}// public functionpub fn jump() {// call private function focus and shift inside the modulefocus();shift();println!("called player::jump");}
}fn main() {// call public function jump from player moduleplayer::jump();
}

called player::focus
called player::shift
called player::jump

在这里,我们在player模块内定义了多个函数。请注意,我们能够在同一模块内的另一个函数jump()中调用私有函数focus()


模块嵌套

一个模块中还可以在定义其他模块,这就是模块的嵌套;看例子:

rust">// nested module
pub mod player {pub mod sprite {pub fn create() {println!("called player::sprite::create");}}
}fn main() {// call public function create from sprite module which is inside player module player::sprite::create();
}

输出:

called player::sprite::create

在这里,我们将一个 sprite 模块嵌套在 player 模块内部。我们在 sprite 模块内定义了一个名为 create() 的公共函数,在 main() 函数中通过 player::sprite::create() 调用。


use关键字

我们可以使用use关键字将模块内的项目引入当前作用域。use关键字帮助我们消除调用函数时写出完整模块路径的需要。让我们通过使用use关键字来重新编写我们的嵌套模块示例。

rust">// nested module
pub mod player {pub mod sprite {pub fn create() {println!("called player::sprite::create");}}
}// bring the create function into scope
use player::sprite::create;fn main() {// call public function directlycreate();
}

这里,我们使用 use 关键字从 player 模块内部的 sprite 模块中将 create() 函数引入当前作用域。

这样我们可以直接调用 create() 函数,而不需要完全限定名称为 player::sprite::create()。


Crate和Package

一个 crate 可以包含一个或多个 Rust 模块,这些模块可以包含诸如函数、类型和常量之类的代码。

一个 crate 有两种类型:二进制 crate 和库 crate。二进制 crate 是一个 Rust 程序,编译成一个可执行文件或多个可执行文件,并且每个可执行文件都有一个 main() 函数。

crate 不会编译成可执行文件,也没有 main() 函数。库 crate 通常定义了可以在多个项目中使用的共享功能。Crates 可以捆绑在一起形成一个 package


可以使用内置在Rust中的Cargo软件包管理器来创建软件包。 Cargo与Rust一起预安装。我们可以使用 cargo 来创建一个软件包。一个软件包包含一个或多个提供一组功能的crate。

一个包中可以包含许多二进制 crate,但最多只能包含一个库 crate。


创建二进制包

要创建一个二进制包,我们可以在终端中使用 cargo 命令。

$ cargo new hello_world --bin

我们使用 cargo --bin选项创建一个二进制包 hello_world。 这是 cargo 的默认行为。 让我们来看看 hello_world 包的内容。

rust">hello_world
├── Cargo.toml
└── src└── main.rs
  • hello_world 是包目录
  • Cargo.toml 是一个包含有关 crate 的元数据的文件,如其名称、版本和依赖项
  • src/main.rs crate 根目录,包含二进制包的源代码

创建库包

$ cargo new hello_world_lib --lib

包结构如下:

rust">hello_world_lib
├── Cargo.toml
└── src└── lib.rs
  • hello_world_lib 是包目录
  • Cargo.toml 是一个包含有关包的元数据的文件,例如其名称、版本和依赖关系
  • src/lib.rs 是 crate 根目录,包含库包的源代码

一个包可以包含src/main.rssrc/lib.rs。在这种情况下,它有两个 crate:一个二进制 crate 和一个库 crate,两者都与包的名称相同。例如,

rust">hello_world
├── Cargo.toml
└── src└── lib.rs└── main.rs

Cargo包管理器

Cargo

CargoRust的包管理器。它与Rust一起预装,并可用于打包依赖项,管理它们以及构建和分发我们自己的包/库。

cargo的特点:

  • 依赖管理

Cargo 可轻松管理我们项目的依赖项,包括添加、更新和删除依赖项。
构建和打包

Cargo 可自动构建和打包我们的 Rust 项目,创建可与他人共享的二进制或库代码。

  • 文档生成

Cargo 可自动为我们的代码生成文档,使其他开发人员更容易理解和使用我们的库。

  • 下载 crate

Cargo 可从 crates.io 下载并安装库,这是 Rust crate 的中央存储库。

  • 运行二进制或测试

Cargo 可构建我们的源代码,运行可执行二进制文件,并运行我们的测试。


依赖管理

Cargo 的主要功能之一是可以下载、管理外部库。让我们看看如何从 crates.io 使用外部 crate 的示例。crates.io 是一个中央仓库,我们可以从中获取和发布用于 Rust 的共享库。

  • 创建一个项目
rust">$ cargo new hello_world
  • 添加一个生成随机数的依赖rand,我们可以在cargo.toml中的[dependencies]部分进行添加
rust">name = "hello_world"
version = "0.1.0"
edition = "2021"# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html[dependencies]
rand = "0.8.5"

我们还可以使用命令 cargo add rand 来为我们的项目添加依赖。

注意,如果通过命令的方式添加依赖,在添加时Rust就会加载编译该依赖,而通过cargo.toml手动添加时,程序会在你首次运行程序时进行加载编译的操作。

  • 使用依赖
rust">use rand::Rng;fn main() {let mut rng = rand::thread_rng();// simulate rolling a dieprintln!("roll = {}", rng.gen_range(1..=6));
}# Output: roll = 5

构建和执行

Rust支持使用cargo命令对程序进行buildrun.命令分别是

  • cargo build
  • cargo run

一般情况下,执行cargo run时,默认会自动执行cargo build,所以一般我们需要运行程序时不需要先执行build,再执行run,而是直接执行cargo run即可。

常用命令一览表:

CommandDescription
cargo newCreate a new Rust project with basic directory structure
cargo buildBuild (compile) the current project and generate a binary executable
cargo runBuild and run your current project (cargo build + run)
cargo checkBuild the current project without generating a binary executable
cargo addAdd a new dependency and include it in Cargo.toml file
cargo updateUpdate all dependencies of current project to latest version

http://www.ppmy.cn/server/48618.html

相关文章

PostgreSQL17优化器改进(3)在使用包含操作符<@和@>时优化范围查询

PostgreSQL17优化器改进&#xff08;3&#xff09;在使用包含操作符<和>时优化范围查询 本文将介绍PostgreSQL 17服务端优化器在使用包含操作符<和>时优化范围查询。其实在在第一眼看到官网网站的对于该优化点的时候&#xff0c;可能是由于缺乏对于范围类型的认知…

redis序列化

文章目录 1、为什么要进行序列化操作&#xff1f;2、序列化方式2.1、自定义序列化2. 2、StringRedisTemplate&#xff08;重点&#xff09; 1、为什么要进行序列化操作&#xff1f; 不进行序列化向redis存入数据代码&#xff1a; SpringBootTest class RedisDemoApplicationT…

SQL Developer迁移第三方数据库单表到Oracle

在SQL Developer中&#xff0c;除可用Migration Wizard迁移第三方数据库到Oracle外&#xff0c;单表的迁移可以用Copy To Oracle ...菜单。右键单击源表即可。 本例的源表为MySQL数据库employees中的表&#xff1a;departments。 Options页面&#xff1a;指定目标库&#xff…

富格林:了解实情摆脱暗箱被骗

富格林悉知&#xff0c;就当下的投资市场看投资者一般会特别关注盈利效率高的产品&#xff0c;而近年来兴起的现货黄金恰恰就符合这个条件。不过新手投资者不了解市场实情&#xff0c;其实很难去判断和摆脱其中的暗箱而导致被骗。因此学会了解实情对于摆脱暗箱被骗极其重要&…

深度学习的点云检测

深度学习的点云检测 点云检测是计算机视觉和图形学中的一项重要任务&#xff0c;旨在识别和定位三维点云数据中的特定物体或区域。点云数据由大量三维点组成&#xff0c;每个点包含空间坐标&#xff08;x, y, z&#xff09;&#xff0c;有时还包含颜色、法向量等附加信息。点云…

Django 里实现表格内容上传

先看效果图&#xff1a; 当没有添加数据&#xff0c;就按 提交 键就会出现报错 下面是操作步骤 1. 先在 views.py 文件里做添加 # 在 views.py class AssetModelForm(forms.ModelForm):#newField forms.CharField()class Meta:model models.AssetSet fields [name, pri…

b站视频下载到电脑本地mp4格式,b站视频下载到手机相册

有时候我们想把网站上的视频下载到电脑或手机&#xff0c;其实有多种方法可供选择。本文将详细介绍几种常见的下载方式&#xff0c;并探讨它们的优缺点&#xff0c;帮助读者根据自己的需求选择最适合的下载方法。 方法一&#xff1a; 1、使用 "小白兔视频格式在线转换网站…

诺派克ROPEX控制器维修RES-5008 RES-5006

德国希尔科诺派克ROPEX热封控制器维修型号包括&#xff1a;RES-401&#xff0c;RES-402&#xff0c;RES-403&#xff0c;RES-406&#xff0c;RES-407&#xff0c;RES-408&#xff0c;RES-409&#xff0c;RES-420&#xff0c;RES-440&#xff0c;RES-5008&#xff0c;RES-5006&a…