Rust极简教程

打印 上一主题 下一主题

主题 1018|帖子 1018|积分 3054

据说,Rust语言语法的高门槛是劝退很多人上手的主要原因。
确实,Rust语言希望解决 C/C++ 手工管理内存的问题,但是又不想引入类似golang,java的GC机制。
因此,为了能让编译器能够在编译阶段检查出潜在的内存问题,Rust的语法上就多了一些其他语言所没有的规则,这些规则让上手Rust的难度提高了不少。
我是觉得,学习一门编程语言,不一定要弄懂其中的所有概念才能开始写代码,就像我们学习外语,掌握了基本几句话之后其实就可以开始对话练习。
这篇极简教程的目的,其实不只是针对Rust,任何编程语言都可以有这么一个极简教程,让大家可以尽快用这种编程语言先把代码写起来,边写边学,不断加深对语言的理解。
因为是极简教程,大纲也很简单,主要3部分:

  • 工程管理
  • 变量定义
  • 流程控制
《C程序设计语言》中有一句很经典话:程序 = 数据结构 + 算法
上面的【变量定义】其实就是数据结构,【流程控制】就是算法,有了这2部分其实就可以编写各种功能。
最后加了【工程管理】这部分,一方面是因为Rust的管理工具Cargo是它的重要特色之一;另一方面,良好的代码组织是完成复杂功能的基础,毕竟我们学习Rust,最后是希望用它去完成实际的业务功能的。
工程管理

通过 cargo 创建 Rust项目,可以更好的管理项目的依赖,打包和升级等等。
所以,尽管是极简教程,还是希望能用 cargo 来管理项目。
Rust项目一般有两种类型,可执行文件和库。
我们一般做的软件或者工具最终都会发布成可执行文件,给用户使用。
而库不能单独运行,一般是对重要的功能进行封装,然后作为其他软件的一部分来使用。
创建可执行文件
  1. cargo new rust-examples
  2. tree .  # 工程结构如下
  3. .
  4. ├── Cargo.toml # 这里是工程的配置
  5. └── src
  6.     └── main.rs
复制代码
其中 main.rs 是启动文件,学习Rust各种语法的时候,可以将代码写在 main.ts 中进行测试。
创建库
  1. cargo new --lib rust-lib
  2. tree .
  3. .
  4. ├── Cargo.toml  # 这里是工程的配置
  5. └── src
  6.     └── lib.rs
复制代码
这里的 lib.rs 和 main.rs 不同,它是不能直接运行的,需要通过里面的测试代码来运行相应的功能。
变量定义

Rust的基本类型和其他语言大同小异,熟悉其他语言(C/C++, golang等)的话,很容易理解。
这里我们构造一个简单的学生成绩管理系统,通过定义学生信息,演示下Rust中基本类型以及枚举和结构体的使用。
  1. cargo new stu_manager
复制代码
在 src/main.rs 中定义并打印学生信息。
  1. #[derive(Debug)]
  2. enum Sex {
  3.     Boy,
  4.     Girl,
  5. }
  6. struct Student {
  7.     name: String, // 姓名
  8.     age: u16,     // 年龄
  9.     sex: Sex,     // 性别
  10.     score: f32,   // 成绩
  11. }
  12. fn main() {
  13.     let students: [Student; 2] = [
  14.         Student {
  15.             name: String::from("boy01"),
  16.             age: 18,
  17.             sex: Sex::Boy,
  18.             score: 61.5,
  19.         },
  20.         Student {
  21.             name: String::from("girl01"),
  22.             age: 16,
  23.             sex: Sex::Girl,
  24.             score: 91.5,
  25.         },
  26.     ];
  27.     display(&students[0]);
  28.     display(&students[1]);
  29. }
  30. fn display(stu: &Student) {
  31.     println!(
  32.         "name: {}, age: {}, sex:{:?}, score: {}",
  33.         stu.name, stu.age, stu.sex, stu.score
  34.     );
  35. }
复制代码
说明:

  • #[derive(Debug)]这个是为了打印enum,否则enum类型是不能直接打印的。
  • struct Student这个结构体中定义了常用的基本类型的使用方式。
  • let students: [Student; 2]Rust数组的定义方式。
与其他语言相比,Rust变量的一个新的概念就是所有权和借用规则,我的另一篇博客中有介绍,这里不在赘述。
Rust所有权和借用规则示例
除此之外,使用的方式和其他语言区别不大,上面示例中,创建了2个学生信息,并且分别打印出其中各个字段的信息。
  1. $ cargo run
  2. Finished dev [unoptimized + debuginfo] target(s) in 0.01s
  3. Running `target/debug/stu_manager`
  4. name: boy01, age: 18, sex:Boy, score: 61.5
  5. name: girl01, age: 16, sex:Girl, score: 91.5
复制代码
流程控制

掌握了变量定义,可以组织我们的数据,再掌握Rust中的流程控制方法,那么,就能实现实际的业务功能了。
流程控制主要两种:分支和循环。
分支

Rust的分支语法有 if和match两种方式。
继续完善上面的例子,我们增加一个根据成绩区分优良中差的函数,用 if的方式来判断分支。
  1. fn check_score(stu: &Student) {
  2.     if stu.score >= 90.0 {
  3.         println!("学员:{}, 成绩优秀", stu.name);
  4.     } else if stu.score < 90.0 && stu.score >= 75.0 {
  5.         println!("学员:{}, 成绩良好", stu.name);
  6.     } else if stu.score < 75.0 && stu.score >= 60.0 {
  7.         println!("学员:{}, 成绩中等", stu.name);
  8.     } else {
  9.         println!("学员:{}, 成绩不合格!!!", stu.name);
  10.     }
  11. }
复制代码
再增加一个判断性别的函数,用match的方式来判断分支。
  1. fn check_sex(stu: &Student) {
  2.     match stu.sex {
  3.         Sex::Boy => println!("学员: {} 是男生", stu.name),
  4.         Sex::Girl => println!("学员: {} 是女生", stu.name),
  5.     }
  6. }
复制代码
循环

Rust 循环主要有3种方式:

  • loop 无限循环,自己控制循环退出
  • while 条件循环
  • for 条件循环
下面用3种循环方式分别打印学生信息,学生成绩信息以及学生性别信息。
  1.     // loop 循环示例
  2.     let mut count = 0;
  3.     loop {
  4.         if count == students.len() {
  5.             break;
  6.         }
  7.         display(&students[count]);
  8.         count += 1;
  9.     }
  10.     // while 循环示例
  11.     count = 0;
  12.     while count < students.len() {
  13.         check_score(&students[count]);
  14.         count += 1;
  15.     }
  16.     // for 循环示例
  17.     for stu in students {
  18.         check_sex(&stu);
  19.     }
复制代码
3种循环中,还是 for循环最为见解,这也是我们使用最多的循环方式。
总结

这里可以看出,只要会任何一种编程语言,几乎不需要太多Rust特有的知识,我们也可以用Rust来编写代码。
当然,Rust的优势,比如内存安全和高性能,这里并没有体现。
这篇博客的目的是希望能够尽快将Rust用起来,用起来之后,遇到问题解决问题,在用的过程中逐步理解Rust的高阶概念和语法,一步一步成为Rust高手。
附录

完整的示例如下:
  1. #[derive(Debug)]enum Sex {    Boy,    Girl,}struct Student {    name: String, // 姓名    age: u16,     // 年龄    sex: Sex,     // 性别    score: f32,   // 成绩}fn main() {    let students: [Student; 2] = [        Student {            name: String::from("boy01"),            age: 18,            sex: Sex::Boy,            score: 61.5,        },        Student {            name: String::from("girl01"),            age: 16,            sex: Sex::Girl,            score: 91.5,        },    ];    // loop 循环示例
  2.     let mut count = 0;
  3.     loop {
  4.         if count == students.len() {
  5.             break;
  6.         }
  7.         display(&students[count]);
  8.         count += 1;
  9.     }
  10.     // while 循环示例
  11.     count = 0;
  12.     while count < students.len() {
  13.         check_score(&students[count]);
  14.         count += 1;
  15.     }
  16.     // for 循环示例
  17.     for stu in students {
  18.         check_sex(&stu);
  19.     }}fn display(stu: &Student) {    println!(        "name: {}, age: {}, sex:{:?}, score: {}",        stu.name, stu.age, stu.sex, stu.score    );}fn check_score(stu: &Student) {    if stu.score > 100.0 {        println!("学员:{}, 成绩错误", stu.name);    } else if stu.score = 90.0 {        println!("学员:{}, 成绩优秀", stu.name);    } else if stu.score < 90.0 && stu.score >= 75.0 {        println!("学员:{}, 成绩良好", stu.name);    } else if stu.score < 75.0 && stu.score >= 60.0 {        println!("学员:{}, 成绩中等", stu.name);    } else {        println!("学员:{}, 成绩不合格!!!", stu.name);    }}fn check_sex(stu: &Student) {
  20.     match stu.sex {
  21.         Sex::Boy => println!("学员: {} 是男生", stu.name),
  22.         Sex::Girl => println!("学员: {} 是女生", stu.name),
  23.     }
  24. }
复制代码
  1. $ cargo run
  2.    Compiling stu_manager v0.1.0 (/home/wangyubin/projects/rust/stu_manager)
  3.     Finished dev [unoptimized + debuginfo] target(s) in 0.60s
  4.      Running `target/debug/stu_manager`
  5. name: boy01, age: 18, sex:Boy, score: 61.5
  6. name: girl01, age: 16, sex:Girl, score: 91.5
  7. 学员:boy01, 成绩中等
  8. 学员:girl01, 成绩优秀
  9. 学员: boy01 是男生
  10. 学员: girl01 是女生
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

tsx81429

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表