Rust变量绑定、解构与数据类型

目录Rust简介变量绑定与解构基本类型数值类型字符、布尔、单元类型语句与表达式函数复合类型字符串切片元组结构体枚举数组Rust简介核心特点内存安全:Rust通过其独特的所有权模型来确保内存安全,避免了空指针异常、数据竞争等问题。它不需要垃圾回

目录


Rust简介

核心特点

  • 内存安全:Rust 通过其独特的所有权模型来确保内存安全,避免了空指针异常、数据竞争等问题。它不需要垃圾回收机制,而是通过编译时检查的所有权和生命周期系统来防止内存泄漏和其他常见的内存错误。

  • 并发性:Rust 的所有权模型也使得它能够在编译时检测数据竞争,从而提供了安全的并发编程方式。

  • 高性能:作为一门编译型语言,Rust 产生的机器码可以直接在计算机上运行,没有虚拟机的开销,因此它非常适合用来编写对性能要求极高的应用。

  • 多范式支持:Rust 支持函数式编程、面向对象编程以及过程化编程等多种编程风格。

发展历史

Rust 语言是由 Mozilla Research 的 Graydon Hoare 在 2006 年开始开发的。最初的目的是为了改进 Web 浏览器引擎的性能和安全性。自 2010 年开源以来,Rust 社区不断壮大,吸引了来自全球各地的贡献者。2015 年,Rust 发布了第一个稳定版本 1.0,并且此后每年都会发布新的稳定版本,持续引入新特性和改进。

使用场景

Rust 可以应用于多种场景,包括但不限于:

  • 操作系统内核:由于其内存安全性和高性能,Rust 成为了开发操作系统内核的理想选择。
  • 网络服务:Rust 提供了丰富的库支持,可以用来开发高效稳定的网络服务。
  • 游戏引擎:Rust 的性能优势使其适合于开发游戏引擎,尤其是在需要高度优化的图形渲染和物理模拟方面。
  • 嵌入式系统:Rust 的无运行时库版本(no_std)允许它被用于资源受限的环境,如嵌入式设备。

工具链

Rust 的工具链包括:

  • Cargo:Rust 的包管理器,用于管理依赖关系、构建项目和发布库。
  • Rustfmt:代码格式化工具,帮助保持代码风格的一致性。
  • Clippy:静态分析工具,提供额外的 lint 规则来提高代码质量。

变量绑定与解构

变量绑定

  • 不可变绑定:默认情况下,变量是不可变的。
  • 可变绑定:使用 mut 关键字声明可变变量。

示例代码

fn main() {
    // 不可变绑定
    let x = 5;
    println!("x is: {}", x);

    // 可变绑定
    let mut y = 6;
    y = 7; // 修改 y 的值
    println!("y is now: {}", y);
}

作用域

变量的作用域是从定义它的位置开始,直到其所在的大括号结束。

示例代码

fn main() {
    let x = 5;

    if x > 0 {
        let y = 10;
        println!("y is: {}", y); // 输出 10
    }

    // println!("y is: {}", y); // 编译错误:y 在此处不可见
}

解构

Rust中的模式匹配允许我们以一种更安全的方式处理数据结构。例如,可以使用元组或枚举来解构数据。

fn main() {
    let (a, b) = (10, 20);
    println!("a is {} and b is {}", a, b);

    let color = Color::Red;
    match color {
        Color::Red => println!("红色"),
        Color::Green => println!("绿色"),
        Color::Blue => println!("蓝色"),
    }
}

#[derive(Debug)]
enum Color {
    Red,
    Green,
    Blue,
}

基本类型

基本类型

  • 整数类型:i32, u32, isize, usize 等。
  • 浮点数类型:f32, f64。
  • 字符类型:char(支持 Unicode)。
  • 布尔类型:bool(true, false)。
  • 单元类型:()(类似于 C++ 中的 void)。

示例代码

fn main() {
    let integer: i32 = 99;
    let floating_point: f64 = 2.71828;
    let character: char = 'A';
    let boolean: bool = true;
    let unit: () = ();

    println!("integer is: {}", integer);
    println!("floating_point is: {}", floating_point);
    println!("character is: {}", character);
    println!("boolean is: {}", boolean);
    println!("unit is: {:?}", unit);
}

语句与表达式

在Rust中,语句和表达式有着明确的区别:

  • 语句:执行某个操作但不返回值,如赋值语句。
  • 表达式:计算出一个值,如算术运算。

示例代码:

fn main() {
    let x = 5; // 语句
    let y = { // 表达式
        let x = 3;
        x + 1
    };
    println!("The value of y is: {}", y);
}

复合类型

字符串 (String)

Rust 中的字符串类型主要有两种:Stringstr

String String 类型是一个可变的字符串类型,可以动态增长。

示例代码:

fn main() {
    let mut s = String::from("hello");

    // 修改字符串
    s.push_str(", world!");
    println!("{}", s); // 输出 "hello, world!"

    // 字符串拼接
    let s1 = String::from("hello");
    let s2 = String::from("world");
    let s3 = format!("{} {}", s1, s2);
    println!("{}", s3); // 输出 "hello world"
}

str str 类型是一个不可变的字符串切片,通常用于表示字符串的一部分。

示例代码:

fn main() {
    let s = "hello";
    println!("{}", s); // 输出 "hello"

    // 访问子字符串
    let hello = &s[0..5];
    println!("{}", hello); // 输出 "hello"
}

切片 (Slice)

切片是一种视图类型,可以表示数组或字符串的一部分。

字符串切片

fn main() {
    let s = String::from("hello world");

    // 创建一个字符串切片
    let slice = &s[0..5]; // 包含索引 0 到 4 的字符

    println!("Slice: {}", slice); // 输出 "hello"
}

// 另一种创建字符串切片的方法
fn main() {
    let s = String::from("hello world");

    let slice_start = &s[..5]; // 包含索引 0 到 4 的字符
    let slice_end = &s[6..];   // 包含索引 6 到最后的字符

    println!("Slice start: {}", slice_start); // 输出 "hello"
    println!("Slice end: {}", slice_end);     // 输出 "world"
}

可变字符串切片 (&mut str) 可变字符串切片允许修改字符串的一部分。

fn main() {
    let mut s = String::from("hello world");

    // 创建一个可变字符串切片
    let slice = &mut s[0..5]; // 包含索引 0 到 4 的字符

    // 修改字符串切片
    slice.make_ascii_uppercase(); // 将 "hello" 转换为大写

    println!("Modified string: {}", s); // 输出 "HELLO world"
}

切片的常见操作

遍历切片

fn main() {
    let numbers = [1, 2, 3, 4, 5];
    let slice = &numbers[1..4];

    for number in slice.iter() {
        println!("{}", number);
    }
}

连接切片

fn main() {
    let numbers = [1, 2, 3, 4, 5];
    let slice1 = &numbers[1..3];
    let slice2 = &numbers[3..5];

    let combined_slice: &[i32] = [&slice1[..], &slice2[..]].concat();

    println!("Combined slice: {:?}", combined_slice); // 输出 [2, 3, 4, 5]
}

拷贝切片到新数组

fn main() {
    let numbers = [1, 2, 3, 4, 5];
    let slice = &numbers[1..4];

    let new_array = [0; 3];
    new_array.copy_from_slice(slice);

    println!("New array: {:?}", new_array); // 输出 [2, 3, 4]
}

函数接受切片作为参数

fn main() {
    let numbers = [1, 2, 3, 4, 5];
    let slice = &numbers[1..4];

    println!("Sum: {}", sum(slice));
}

fn sum(slice: &[i32]) -> i32 {
    slice.iter().sum()
}

使用迭代器遍历切片

fn main() {
    let numbers = [1, 2, 3, 4, 5];
    let slice = &numbers[1..4];

    let sum: i32 = slice.iter().sum();
    println!("Sum: {}", sum); // 输出 9
}

数组切片

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

    // 创建一个数组切片
    let slice = &numbers[1..4]; // 包含索引 1 到 3 的元素

    println!("Slice: {:?}", slice); // 输出 [2, 3, 4]
}

// 另一种创建数组切片的方法
fn main() {
    let numbers = [1, 2, 3, 4, 5];

    let slice_start = &numbers[..3]; // 包含索引 0 到 2 的元素
    let slice_end = &numbers[2..];   // 包含索引 2 到最后的元素

    println!("Slice start: {:?}", slice_start); // 输出 [1, 2, 3]
    println!("Slice end: {:?}", slice_end);     // 输出 [3, 4, 5]
}

元组 (Tuple)

元组是一种固定大小的集合,可以包含不同类型的元素。

fn main() {
    let pair = (1, "hello");

    // 访问元组元素
    println!("pair.0 is {}", pair.0); // 输出 1
    println!("pair.1 is {}", pair.1); // 输出 hello

    // 分解元组
    let (a, b) = pair;
    println!("a is {}", a); // 输出 1
    println!("b is {}", b); // 输出 hello
}

数组 (Array)

数组是一种固定大小的序列类型,所有元素必须具有相同的类型。

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

    // 访问数组元素
    println!("numbers[0] is {}", numbers[0]); // 输出 1
    println!("numbers[1] is {}", numbers[1]); // 输出 2

    // 分解数组
    let [a, b, c, d, e] = numbers;
    println!("a is {}", a); // 输出 1
    println!("b is {}", b); // 输出 2
    println!("c is {}", c); // 输出 3
    println!("d is {}", d); // 输出 4
    println!("e is {}", e); // 输出 5
}

向量 (Vector)

向量是一种动态大小的序列类型,可以存储多个相同类型的元素。

fn main() {
    let mut v = Vec::new();

    // 添加元素
    v.push(1);
    v.push(2);
    v.push(3);

    // 访问向量元素
    println!("v[0] is {}", v[0]); // 输出 1
    println!("v[1] is {}", v[1]); // 输出 2

    // 分解向量
    let [a, b, c] = v.as_slice();
    println!("a is {}", a); // 输出 1
    println!("b is {}", b); // 输出 2
    println!("c is {}", c); // 输出 3
}

结构体 (Struct)

结构体是一种用户定义的数据类型,可以包含多个字段。

struct Person {
    name: String,
    age: u32,
}

impl Person {
    fn new(name: String, age: u32) -> Person {
        Person { name, age }
    }
}

fn main() {
    let person = Person::new(String::from("Alice"), 30);

    // 访问结构体字段
    println!("name is {}", person.name); // 输出 Alice
    println!("age is {}", person.age);   // 输出 30

    // 分解结构体
    let Person { name, age } = person;
    println!("name is {}", name); // 输出 Alice
    println!("age is {}", age);   // 输出 30
}

枚举 (Enum)

枚举是一种定义一组相关值的类型。

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

fn main() {
    let m = Message::Write(String::from("hello"));

    // 分解枚举
    match m {
        Message::Quit => println!("quit"),
        Message::Move { x, y } => println!("move to ({}, {})", x, y),
        Message::Write(text) => println!("write: {}", text),
        Message::ChangeColor(r, g, b) => println!("change color to ({}, {}, {})", r, g, b),
    }
}

实现一个简单的数据结构

// 定义任务状态枚举
enum TaskStatus {
    Pending,
    Completed,
}

// 定义任务结构体
struct Task {
    id: usize,
    description: String,
    status: TaskStatus,
}

impl Task {
    fn new(id: usize, description: String) -> Task {
        Task {
            id,
            description,
            status: TaskStatus::Pending,
        }
    }

    fn mark_as_completed(&mut self) {
        self.status = TaskStatus::Completed;
    }

    fn is_completed(&self) -> bool {
        matches!(self.status, TaskStatus::Completed)
    }
}

// 定义任务列表结构体
struct TaskList {
    tasks: Vec<Task>,
}

impl TaskList {
    fn new() -> TaskList {
        TaskList { tasks: Vec::new() }
    }

    fn add_task(&mut self, task: Task) {
        self.tasks.push(task);
    }

    fn complete_task(&mut self, id: usize) {
        if let Some(task) = self.tasks.iter_mut().find(|t| t.id == id) {
            task.mark_as_completed();
        }
    }

    fn print_tasks(&self) {
        for task in &self.tasks {
            println!("Task ID: {}, Description: {}, Status: {:?}", task.id, task.description, task.status);
        }
    }
}

fn main() {
    let mut task_list = TaskList::new();

    let task1 = Task::new(1, String::from("Buy groceries"));
    let task2 = Task::new(2, String::from("Do laundry"));
    let task3 = Task::new(3, String::from("Read book"));

    task_list.add_task(task1);
    task_list.add_task(task2);
    task_list.add_task(task3);

    task_list.print_tasks(); // 输出所有任务

    task_list.complete_task(2);

    println!("After completing task 2:");
    task_list.print_tasks(); // 输出已完成任务
}
  • 原创
  • 学分: 10
  • 分类: Rust
  • 标签: Rust 
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
天涯学馆
天涯学馆
0x9d6d...50d5
资深大厂程序员,12年开发经验,致力于探索前沿技术!