Hello, world!

本篇将讲述如何编译运行单个Rust文件和cargo的初级用法。

首先,为了方便学习编写代码,建议你新建一个learn_rust文件夹,并将学习时的rs文件和Rust项目放进来。

Helllo, world


众所周知,学习一门语言往往从输出Hello, world!开始,因此我们先尝试写出一个能输出Hello, world的Rust程序。

Rust源文件扩展名是rs,因此先在learn_rust文件夹下新建一个文件hello_world.rs,然后用编辑器打开该文件并键入以下内容(注意println!后有一个!):

1
2
3
fn main() {
println!("Hello world!");
}

然后在终端(VSCode下可用Ctrl+Shift+`打开)中键入rustc hello_world.rs编译,windows下会产生.pdb文件和.exe,编译好后输入.\hello_world即可运行输出。

Hello_world.rs编译运行结果

同C/C++一样,Rust程序也是从main()函数开始运行的。在Rust代码中,main()函数的结构如下:

1
2
3
fn main() {
// your code
}

fn关键字用于声明函数,上述代码声明了一个"无返回值"(实际上有返回值,返回值为())的main()函数。

main()函数中,我们调用用了println!()用于输出字符串常量"Hello world",请注意println!()中有个!号,这表明println!()是一个宏(macro)而不是函数println!()宏用于格式化输出

不同于C/C++,Rust的main()函数默认"无返回值"且不能有参数,要想获取命令行参数,可自行阅读std::env::args()的用法。

Hello, cargo


cargo是Rust的包\(^{[1]}\)管理工具,使用cargo能方便的添加依赖、编译链接程序、管理项目。使用rustup安装过程中,cargo也一起被下载安装好了,命令行中输入cargo --help即可看到cargo的参数说明。

接下来让我们用cargo创建一个项目hello_cargo,使其运行输出Hello, cargo!

打开终端cd到learn_rust文件夹下,执行cargo new hello_cargo --bincargo new hello_cargo新建一个二进制项包\(^{[2]}\)(binary package)。

执行后cargo会在learn_rust下生成一个文件夹hello_cargo,这就是新建的二进制包。

hello_cargo文件夹的内容如下(装了RA可能会多出一个Cargo.lock文件和target文件夹,这是编译后的结果):

新建包hello_cargo内容概览

用编辑器打开hello_cargo\Cargo.toml,可以看到如下内容:

hello_cargo\Cargo.toml

Cargo.toml文件是cargo在该包中的配置文件,用来向cargo指明如何编译构造该包,下面我给一个示例简单说明一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Cargo的配置文件采用TOML,TOML语言具体语法说明可参照https://github.com/LongTengDao/TOML/blob/龙腾道-译/toml-v1.0.0.md
# 这里不对TOML的语法做过多展开,只需掌握基础知识即可
# TOML文件注释符为#而不是//

# []用于声明一个表(哈希表),这里声明了一个名为package的表
# 下边跟着的是键值对,因为是哈希表,所以不能出现相同的键
# cargo从[package]中读取该包的相关信息
[package]
name = "hello_cargo" # name键值用于声明该包的名字,默认采用创建时的包名
version = "0.1.0" # version用于声明该包的版本
edition = "2021" # edition用于声明该包编译所使用的Rust版本
#以上三个为必须包含的键值对,要查看可选的键值对请参考https://doc.rust-lang.org/cargo/reference/manifest.html

# [dependencies]意为依赖,这与引入第三方库有关
[dependencies]
# 例如以下键值对表示该包依赖rand库0.8.4版,这是一个生成随机数的库
# 添加后即可直接在main.rs通过use关键字引入rand库,副篇会具体说明
rand = "0.8.4"

编辑器中打开hello_cargo\src\main.rs,可以看到cargo自动生成了和hello_world.rs内容一样的代码。

main.rs里的Hello world!改为Hello cargo!并编译运行。不过这次我们不使用rustc编译后运行,而是直接cd到hello_cargo文件夹下,执行cargo run,即可看到cargo的编译信息,cargo在编译完后就会立刻hello_cargo文件夹下运行编译好的程序。

Hello cargo!

可以看到程序如期输出了Hello cargo!

使用cargo run --help可以查看cargo run各种参数作用解释。例如加上参数--release可以大幅优化程序,但同时会大幅增加编译时间。

tips(如有使用过VCS可以了解以下内容):

使用cargo new新建包时会初始化VCS(版本控制系统,默认会使用git),您可以添加参数--vcs指定使用的VCS类型(git,hg,pijul(Rust编写的VCS),fossil,none(不使用VCS)),例如cargo new name --vcs=none。但如果你尝试在某个仓库里执行cargo newcargo并不会帮你初始化VCS(例如上面hello_cargo概览里并没有.git,因为我在某个仓库里建立了这个包),需要显式地声明使用git:cargo new --vcs=git来初始化git

注解


[1]包

包是cargo中的一个概念,一个符合cargo规则的项目就可以被称为包,如果你觉得描述不清的话,可以直接认为一个包就是一个Rust项目。

项目

什么,连这个都不懂???

如果没接触过多文件编程,可以将项目理解为将文件分到不同的文件夹里,文件夹和其中的文件就可以称为项目,另一种叫法是工程,分项目的好处是你可以把相关资料、工具也放里面,便于管理。

如果接触过多文件编程,那你肯定会把文件都堆到某个文件里,这个文件夹及其内容就称为项目/工程。

[2]二进制包和库

二进制包:该包内的文件编译后的结果为可执行的二进制文件(俗称程序)。

库(library):库也是一种包,一般而言库用于给其他的包提供API等(例如std),当然也可以直接在库中建立二进制包

新建一个库的方法为cargo new name --lib