8.6 KiB
title, date, tags
| title | date | tags |
|---|---|---|
| Rust | 2023-09-15 09:25:54 |
Rust 教程
第一个 Rust 程序
Rust语言代码文件后缀名为.rs,如helloworld.rs。
fn main() {
println!("Hello World!");
}
使用rustc命令编译helloworld.rs文件:
rustc helloworld.rs # 编译 helloworld.rs 文件
编译后会生成helloworld可执行文件:
./helloworld # 执行 helloworld
Hello World!
Rust 环境搭建
安装 Rust 编译工具
Rust 编译工具从链接 安装 Rust - Rust 程序设计语言 (rust-lang.org) 中下载的Rustup安装。下载好的Rustup在Windows 上是一个可执行程序 rustup-init.exe。(在其他平台上应该是rustup-init.sh)。
现在执行 rustup-init 文件:
上图显示的是一个命令行安装向导。
如果你已经安装MSVC(推荐),那么安装过程会非常的简单,输入 1 并回车,直接进入第二步。
如果你安装的是MinGW,那么你需要输入 2(自定义安装),然后系统会询问你 Default host triple?,请将上图中 default host triple的"msvc"改为"gnu"再输入安装程序:
其他属性都默认。
设置完所有选项,会回到安装向导界面(第一张图),这时我们输入 1 并回车即可。
进行到这一步就完成了Rust的安装,可以通过以下命令测试:
rustc -V # 注意大写的 V
如果以上两个命令能够输出你安装的版本号,就是安装成功了。
搭建 Visual Studio Code 开发环境
安装rust-analyzer和Native Debug两个扩展。
重新启动 VsCode,Rust 的开发环境就搭建好了。
现在新建一个文件夹,如 RustLearn。
在VsCode中打开新建的文件夹。
打开文件夹后,新建终端。
输入以下命令:
cargo new greeting
当前文件夹下会构建一个名叫 greeting 的 Rust 的工程目录。
在终端里输入以下三个命令:
cd ./greeting
cargo build
cargo run
系统在创建工程时会生成一个Hello World源程序main.rs,这时会被编译运行:
Cargo 教程
Cargo 是什么
Cargo 是 Rust 的构建系统和包管理器。
Rust 开发者 常用 Cargo 来管理 Rust 工程和获取工程所依赖的库。在上个教程中我们曾使用 cargo new greeting 命令创建一个名为 greeting 的工程,Cargo 新建了一个名为 greeting 的文件夹并在里面部署了一个 Rust 工程最典型的文件结构。这个 greeting 文件夹就是工程本身。
Cargo 功能
Cargo 除了创建工程以外还具备构建(build)工程、运行(run)工程等一系列功能,构建和运行分别对应以下命令:
cargo build
cargo run
Cargo 还具有获取包、打包、高级构建等功能,详细使用方法参见 Cargo 命令。
cargo clippy # 类似ESLint,lint工具检查代码可以优化的地方
cargo fmt # 类似go fmt,代码格式化
cargo tree # 查看第三方库的版本和依赖关系
cargo bench # 运行benchmark(基准测试,性能测试)
cargo udeps # (第三方)检查项目中未使用的依赖
# 另外cargo build/run --release 使用release编译会比默认的debug编译性能提升10倍以上,但是 release 缺点是编译速度较慢,而且不会显示 panic backtrace 的具体行号
在 VsCode 中配置 Rust 工程
Cargo 是一个不错的构建工具,如果使VsCode 与它相配合那么 VsCode 将会是一个十分便捷的开发环境。
在上一章中我们建立了 greeting 工程,现在我们用 VsCode 打开 greeting 文件夹**(注意不是 RustLeanrning)**。
打开 greeting 之后,在里面新建一个新的文件夹.vscode
Rust 输出到命令行
在正式学习 Rust 语言以前,我们需要先学会怎样输出一段文字到命令行,这几乎是学习每一门语言之前必备的技能,因为输出到命令行几乎是语言学习阶段程序表达结果的唯一方式。
在之前的 Hello, World 程序中大概已经告诉了大家输出字符串的方式,但并不全面,大家可能很疑惑为什么 println!( "Hello World") 中的 println 后面还有一个 ! 符号,难道 Rust 函数之后都要加一个感叹号?显然并不是这样。println 不是一个函数,而是一个宏规则。这里不需要更深刻的挖掘宏规则是什么,后面的章节中会专门介绍,并不影响接下来的一段学习。
Rust 输出文字的方式主要有两种:println!() 和 print!()。这两个"函数"都是向命令行输出字符串的方法,区别仅在于前者会在输出的最后附加输出一个换行符。当用这两个"函数"输出信息的时候,第一个参数是格式字符串,后面是一串可变参数,对应着格式字符串中的"占位符",这一点与 C 语言中的 printf 函数很相似。但是,Rust 中格式字符串中的占位符不是 "% + 字母" 的形式,而是一对 {}。
printlna.rs文件
fn main() {
let a = 12;
println!("a is {}", a);
}
使用rustc命令编译printlna.rs文件:
rustc printlna.rs # 编译 printlna.rs 文件
编译后会生成 printlna可执行文件:
./printlna # 执行 printlna
以上程序的输出结果是:
a is 12
如果我想把 a 输出两遍,那岂不是要写成:
println!("a is {}, a again is {}", a, a);
其实有更好的写法:
println!("a is {0}, a again is {0}", a);
在{}之间可以放一个数字,它将把之后的可变参数当做一个数组来访问,下标从0开始。
如果要输出 { 或 } 怎么办呢?格式字符串通过 {{ 和 }} 分别转义代表 { 和 } 。但是其他常用转义字符与 C 语言里的转义字符一样,都是反斜杠开头的形式。
fn main() {
println!("{{}}");
}
以上程序的输出结果是:
{}
Rust 基础语法
变量,基本类型,函数,注释和控制流,这些几乎是每种编程语言都具有的编程概念。
这些基础概念将存在于每个 Rust 程序中,及早学习它们将使你以最快的速度学习 Rust 的使用。
变量
首先必须说明,Rust 是强类型语言,但具有自动判断变量类型的能力。这很容易让人与弱类型语言产生混淆。
如果要声明变量,需要使用 let 关键字。例如:
let a = 123;
只学习过 JavaScript 的开发者对这句话很敏感,只学习过 C 语言的开发者对这句话很不理解。
在这句声明语句之后,以下三行代码都是被禁止的:
a = "abc";
a = 4.56;
a = 456;
第一行的错误在于当声明 a 是 123 以后,a 就被确定为整型数字,不能把字符串类型的值赋给它。
第二行的错误在于自动转换数字精度有损失,Rust 语言不允许精度有损失的自动数据类型转换。
第三行的错误在于 a 不是个可变变量。
前两种错误很容易理解,但第三个是什么意思?难道 a 不是个变量吗?
这就牵扯到了 Rust 语言为了高并发安全而做的设计:在语言层面尽量少的让变量的值可以改变。所以 a 的值不可变。但这不意味着 a 不是"变量"(英文中的 variable),官方文档称 a 这种变量为"不可变变量"。
如果我们编写的程序的一部分在假设值永远不会改变的情况下运行,而我们代码的另一部分在改变该值,那么代码的第一部分可能就不会按照设计的意图去运转。由于这种原因造成的错误很难在事后找到。这是 Rust 语言设计这种机制的原因。
当然,使变量变得"可变"(mutable)只需一个 mut关键字。
let mut a = 123;
a = 456;
这个程序是正确的。
常量与不可变变量的区别
既然不可变变量是不可变的,那不就是常量吗?为什么叫变量?
变量和常量还是有区别的。在 Rust 中,以下程序是合法的:
let a = 123; // 可以编译,但可能有警告,因为该变量没有被使用
let a = 456;






