Rust 学习笔记(一)

本文是博主学Rust的学习笔记,将学习经历整理下来,学习接收的内容更加条理且以便回顾。

参照学习资料为Rust官方文档,如内容中有误还请指点(一般没有☺)

一. 项目搭建

1.创建项目

复制代码
cargo new hello_cargo
cd hello_cargo

2.构建项目

复制代码
cargo build

3.运行项目

复制代码
./target/debug/hello_cargo 

文件运行成功

也可以使用cargo run

复制代码
cargo run

Cargo 还提供了一个名为 cargo check 的命令。 该命令可快速检查你的代码,确保它能编译但不会生成可执行文件

复制代码
cargo check

二. 变量

1. 默认变量不可变

复制代码
fn main() {
    let x = 5;
    println!("The value of x is: {x}");
    x = 6;
    println!("The value of x is: {x}");
}

报错

2. 实现变量可变,添加mut

复制代码
fn main() {
    let mut x = 5;
    println!("The value of x is: {x}");
    x = 6;
    println!("The value of x is: {x}");
}

3. 常量

使用大写英文字母,单词和单词之间使用下划线

复制代码
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;

4. 阴影

复制代码
fn main() {
    let x = 5;

    let x = x + 1;

    {
        let x = x * 2;
        println!("The value of x in the inner scope is: {x}");
    }

    println!("The value of x is: {x}");
}

这个程序首先将 x 绑定为 5。 然后通过重复 let x = 创建一个新变量 x,将原来的值加上 1,这样 x 的值就是 6。 然后,在用大括号创建的内部作用域中,第三条 let 语句也对 x 进行了阴影处理,并创建了一个新变量,将原来的值乘以 2,使 x 的值为 12。 当该作用域结束时,内部阴影结束,x 返回到 6

三. 数据类型

1. 标量

(1)整型

Length Signed Unsigned
8-bit i8 u8
16-bit i16 u16
32-bit i32 u32
64-bit i64 u64
128-bit i128 u128
arch isize usize

isize 和 usize 类型取决于程序运行的计算机体系结构,表中用 "arch "表示: 如果是 64 位架构,则为 64 位;如果是 32 位架构,则为 32 位。

(2)数字字面量

类型 前缀 示例 十进制值 适用场景
十进制 98_222 98222 常规数值
十六进制 0x 0xff 255 位操作、内存地址
八进制 0o 0o77 63 文件权限掩码
二进制 0b 0b1111_0000 240 位标志、硬件寄存器
字节 b' b'A' 65 u8 类型ASCII字符

(3)浮点类型

Rust 还为浮点数(带有小数点的数)提供了两种原始类型。 Rust 的浮点类型是 f32 和 f64,大小分别为 32 位和 64 位。 默认类型是 f64,因为在现代 CPU 上,它的速度与 f32 大致相同,但精度更高。 所有浮点类型都是带符号的。

复制代码
fn main() {
    let _x = 2.0; // f64

    let _y: f32 = 3.0; // f32
}

(4)数字运算

示例代码

复制代码
fn main() {
    // addition
    let _sum = 5 + 10;

    // subtraction
    let _difference = 95.5 - 4.3;

    // multiplication
    let _product = 4 * 30;

    // division
    let _quotient = 56.7 / 32.2;
    let _truncated = -5 / 3; // Results in -1

    // remainder
    let _remainder = 43 % 5;
}

(5)布尔类型

与大多数其他编程语言一样,Rust 中的布尔类型有两个可能的值:true 和 false。 布尔值的大小为一个字节。 Rust 中的布尔类型用 bool

代码示例

复制代码
fn main() {
    let t = true;

    let f: bool = false; // with explicit type annotation
}

(6)字符类型

Rust 的 char 类型是该语言最原始的字母类型。

代码示例

复制代码
#[allow(non_snake_case)] // 禁用蛇形命名检查
fn main() {
    let _c = 'z';
    let _z: char = 'ℤ';
    let Heart_Eyed_Cat = '😻'; // 保持原名(不推荐)
    println!("{}", _c);
    println!("{}", _z);
    println!("{}", Heart_Eyed_Cat);
}

运行结果

2. 复合类型

(1)元组类型

元组是将多种类型的数值组合成一个复合类型的通用方法。 元组有固定的长度:一旦声明,其大小就不能增大或缩小。 我们在括号内写入一个逗号分隔的值列表,就创建了一个元组。 元组中的每个位置都有一个类型,元组中不同值的类型不一定相同。

例如

复制代码
fn main() {
    let tup: (i32, f64, u8) = (500, 6.4, 1);
}

变量 tup 与整个元组绑定,因为元组被视为一个单一的复合元素。 要从元组中获取单个值,我们可以使用模式匹配来重组元组值

复制代码
fn main() {
    let tup = (500, 6.4, 1);

    let (x, y, z) = tup;

    println!("The value of y is: {y}");
}

我们也可以直接访问一个元组元素,方法是使用句号(.),后面跟上我们要访问的值的索引

复制代码
fn main() {
    let x: (i32, f64, u8) = (500, 6.4, 1);

    let five_hundred = x.0;

    let six_point_four = x.1;

    let one = x.2;
}

没有任何值的元组有一个特殊的名称,即 unit。 这个值及其对应的类型都被写成(),代表空值或空返回类型。 如果表达式不返回任何其他值,则隐式返回单位值。

(2)数组类型

数组的每个元素都必须具有相同的类型。 与其他一些语言中的数组不同,Rust 中的数组有固定的长度。我们将数组中的值以逗号分隔的列表形式写在方括号内。

复制代码
fn main() {
    let a = [1, 2, 3, 4, 5];
}

在写数组类型时,可以用方括号写出每个元素的类型、分号,然后写出数组中元素的个数

复制代码
let a: [i32; 5] = [1, 2, 3, 4, 5];

也可以通过指定初始值、分号和方括号中的数组长度来初始化数组,使每个元素都包含相同的值

复制代码
let a = [3; 5];
a. 访问数组元素

数组是一块已知固定大小的内存,可以在堆栈上分配。 你可以使用索引访问数组中的元素

复制代码
fn main() {
    let a = [1, 2, 3, 4, 5];

    let first = a[0];
    let second = a[1];
}
b. 无效数组元素访问

尝试访问数组中超过数组末尾的元素会发生什么。 假设运行这段代码

复制代码
use std::io;

fn main() {
    let a = [1, 2, 3, 4, 5];

    println!("Please enter an array index.");

    let mut index = String::new();

    io::stdin()
        .read_line(&mut index)
        .expect("Failed to read line");

    let index: usize = index
        .trim()
        .parse()
        .expect("Index entered was not a number");

    let element = a[index];

    println!("The value of the element at index {index} is: {element}");
}

该代码编译成功。 如果使用 cargo run 运行这段代码并输入 0、1、2、3 或 4,程序将打印出数组中该索引处的相应值。 如果你输入一个超过数组末尾的数字,例如 10

报错

程序在索引操作中使用无效值时出现运行时错误。 程序带着错误信息退出,并且没有执行最后的 println! 当你尝试使用索引访问元素时,Rust 会检查你指定的索引是否小于数组长度。 如果索引大于或等于长度,Rust 就会惊慌失措。 这种检查必须在运行时进行,尤其是在这种情况下,因为编译器不可能知道用户稍后运行代码时会输入什么值。

这是 Rust 内存安全原则发挥作用的一个例子。 在许多底层语言中,这种检查是不存在的,当你提供了一个不正确的索引时,无效的内存就会被访问。

相关推荐
齐生13 小时前
iOS 知识点 - IAP 是怎样的?
笔记
tingshuo291717 小时前
D006 【模板】并查集
笔记
DongLi0121 小时前
rustlings 学习笔记 -- exercises/06_move_semantics
rust
ssshooter1 天前
Tauri 踩坑 appLink 修改后闪退
前端·ios·rust
布列瑟农的星空1 天前
前端都能看懂的rust入门教程(二)——函数和闭包
前端·后端·rust
tingshuo29172 天前
S001 【模板】从前缀函数到KMP应用 字符串匹配 字符串周期
笔记
蚂蚁背大象2 天前
Rust 所有权系统是为了解决什么问题
后端·rust
布列瑟农的星空2 天前
前端都能看懂的rust入门教程(五)—— 所有权
rust
Java水解3 天前
Rust嵌入式开发实战——从ARM裸机编程到RTOS应用
后端·rust
Pomelo_刘金3 天前
Rust:所有权系统
rust