RUST:一篇入门
Rust语言入门指南
前言
Rust是一种系统编程语言,它提供了高性能
和内存安全性
。它特别适合编写底层系统代码
,如操作系统、文件系统和嵌入式系统,同时也适用于构建网络服务和Web应用。本文将带你走进Rust的世界,了解其基本语法和核心概念✍。
1. ⚙️ 安装Rust
首先,你需要在你的计算机上安装Rust。你可以访问Rust的官方网站rust的安装,并按照说明进行安装。
安装完成后,你可以通过打开终端或命令提示符并输入rustc --version
或rustup show
来验证Rust是否已成功安装。
2. ✍ 编写第一个Rust程序
在Rust中,源文件通常使用.rs
作为扩展名。让我们创建一个简单的“Hello, World!”程序来开始我们的Rust之旅。
创建一个新的文件,命名为hello.rs
,并输入以下代码:
fn main() {
println!("Hello, World!");
}
这段代码定义了一个名为main
的函数,该函数是Rust程序的入口点。在main
函数内部,我们调用了println!
宏来打印出“Hello, World!”。
要编译并运行这个程序,打开终端,导航到包含hello.rs
文件的目录,并运行以下命令:
rustc hello.rs
./hello
你应该会在终端中看到输出“Hello, World!”。
3. ❄️ 变量和数据类型
3.1 变量示例
在Rust中,你可以使用let
关键字来声明变量。Rust是一种静态类型语言,这意味着在编译时就需要知道变量的类型。但是,Rust也提供了类型推断功能,可以在大多数情况下自动推断出变量的类型。
以下是一个示例,展示了如何在Rust中声明和使用变量:
fn main() {
let x = 5; // 整数类型,Rust推断为i32
let y = 3.14; // 浮点数类型,Rust推断为f64
let greeting = "Hello, Rust!"; // 字符串类型,Rust使用UTF-8编码的字符串切片
println!("x = {}", x);
println!("y = {}", y);
println!("greeting = {}", greeting);
}
🐊 需要注意的是:以let x = 5
为例,使用let
来声明变量,进行绑定,变量x是不可变的
。
Rust还提供了丰富的数据类型,包括整数、浮点数、布尔值、字符、元组、数组、切片、枚举和结构体等。
3.1 数据类型
- 数值类型: 有符号整数 (i8, i16, i32, i64, isize)、 无符号整数 (u8, u16, u32, u64, usize) 、浮点数 (f32, -f64)、以及有理数、复数
- 字符串:字符串字面量和字符串切片 &str
- 布尔类型: true和false
- 字符类型: 表示单个 Unicode 字符,存储为 4 个字节
- 单元类型: 即 () ,其唯一的值也是 ()
🐊 还是以let x = 5
为例,你不必显式地声明变量的类型,Rust 编译器很聪明,它可以根据变量的值和上下文中的使用方式来自动推导出变量的类型。
4. 🎶 函数
在Rust中,函数是执行特定任务的可重用代码块。函数可以接收参数并返回值。以下是一个带有参数和返回值的函数示例:
4.1 示例
fn add(x: i32, y: i32) -> i32 {
x + y
}
fn main() {
let sum = add(5, 3);
println!("The sum is {}", sum); // 输出 "The sum is 8"
}
在这个示例中,add
函数接收两个i32
类型的参数x
和y
,并返回它们的和(也是i32
类型)。在main
函数中,我们调用了add
函数,并将结果存储在sum
变量中。
5. 🙌 控制流
Rust支持多种控制流结构,包括条件语句(if
/else
)、循环(for
、while
和loop
)以及匹配(match
)。这些结构可以帮助你根据条件执行不同的代码块或重复执行代码块。
以下是一个使用if
/else
条件语句的示例:
fn main() {
let number = 7;
if number % 2 == 0 {
println!("{} is even", number);
} else {
println!("{} is odd", number);
}
}
这个示例检查一个数字是否是偶数,并打印相应的消息。
6. 💖 所有权和借用
Rust 之所以能成为万众瞩目的语言,就是因为其内存安全性。
在以往,内存安全几乎都是通过 GC 的方式实现(例如 java 和 go 🙂),但是 GC 会引来性能、内存占用以及 Stop the world 等问题,在高性能场景和系统编程上是不可接受的,因此 Rust 采用了与 ( 不 ) 众 ( 咋 ) 不 ( 好 ) 同 ( 学 )
的方式:所有权系统。
6.1 所有权
关于所有权的规则,首先请谨记以下规则:
- Rust 中每一个值都被一个变量所拥有,该变量被称为值的所有者
- 一个值同时只能被一个变量所拥有,或者说一个值只能拥有一个所有者
- 当所有者(变量)离开作用域范围时,这个值将被丢弃(drop)
{ // s 在这里无效,它尚未声明
let s = "hello"; // 从此处起,s 是有效的
// 使用 s
} // 此作用域已结束,s不再有效
转移所有权
let x = 5;
let y = x;
这段代码并没有发生所有权的转移
let s1 = String::from("hello");
let s2 = s1;
当变量离开作用域后,Rust 会自动调用 drop 函数并清理变量的堆内存。不过由于两个 String 变量指向了同一位置。这就有了一个问题:当 s1 和 s2 离开作用域,它们都会尝试释放相同的内存。这是一个叫做 二次释放(double free) 的错误,也是之前提到过的内存安全性 BUG 之一。两次释放(相同)内存会导致内存污染,它可能会导致潜在的安全漏洞。
🐊因此,Rust 这样解决问题:当 s1 被赋予 s2 后,Rust 认为 s1 不再有效,因此也无需在 s1 离开作用域后 drop 任何东西,这就是把所有权从 s1 转移给了 s2,s1 在被赋予 s2 后就马上失效了。
6.1 借用
如果仅仅支持通过转移所有权的方式获取一个值,那会让程序变得复杂。 Rust 能否像其它编程语言一样,使用某个变量的指针或者引用呢?答案是可以。
Rust 通过 借用(Borrowing)
这个概念来达成上述的目的,获取变量的引用,称之为借用(borrowing)。
🐊正如现实生活中,如果一个人拥有某样东西,你可以从他那里借来,当使用完毕后,也必须要物归原主。