当前位置:   article > 正文

Rust 学习笔记_rust编程语言 笔记

rust编程语言 笔记

Rust 学习笔记


Hello, World!

fn main() {
	println!("Hello, World!");
}
  • 1
  • 2
  • 3

编译与运行Rust程序

  • 编译:rustc main.rs
  • 运行:
    • Windows:.\main.exe
    • Linux/Mac:./main

Rust程序解剖

  • 定义函数:fn main() {}
    • 没有参数,没有返回
  • main 函数很特别,它是每个Rust可执行程序最先运行的代码
  • 打印文本:println!("Hello, World!")
    • Rust的缩进是4个空格,而不是tab
    • println! 是一个Rust macro(宏)
      • 如果是函数的话,就没有!
    • "Hello, World!"是字符串,它是println!的参数
    • 这行代码以;结尾

编译和运行是单独的两步

  • 运行Rust程序之前必须编译,命令为rustc 源文件名
    • rustc main.rs
  • 编译成功后,会生成一个二进制文件
    • 在Windows上还会生成一个.pdb文件,里面包含调试信息
  • Rust是ahead-of-time编译的语言
    • 可以先编译程序,然后把可执行文件交给别人运行(无需安装Rust)
  • rustc 只适合编译简单的Rust程序

Hello Cargo

Cargo

  • Caogo是Rust的构建系统和包管理工具
    • 构建代码、下载依赖的库、构建这些库…
  • 安装Rust的时候会安装Cargo
    • cargo --version

使用Cargo创建项目

  • 创建项目:cargo new hello_cargo
    • 项目名称也是hello_cargo
    • 会创建一个新的目录hello_cargo
      • Cargo.toml
      • src目录
        • main.rs
      • 初始化了一个新的GIt仓库,.gitignore
        • 可以使用其他VCS或不使用VCS:cargo new 的时候使用 --vcs 这个flag

Cargo.toml

  • TOML(Tom’s Obvious, Minimal Language)格式,是Cargo的配置格式
  • [package],是一个区域标题,表示下方的内容是用来配置包(package)的
    • name,项目名
    • version,项目版本
    • authors,项目作者
    • edition,使用的Rust版本
  • [dependencies],另一个区域的开始,它会列出项目的依赖项
  • 在Rust里面,代码的包称做crate

src/main.rs

  • cargo生成的main.rs在是src目录下
  • 而Cargo.toml在项目顶层下
  • 源代码都应该在src目录下
  • 顶层目录可以放置:README、许可信息、配置文件和其他与程序源码无关的文件
  • 如果创建项目时没有使用cargo,也可以把项目转换为使用cargo:
    • 把源代码文件移动到src下
    • 创建Cargo.toml并填写相应配置

构建项目 cargo build

  • cargo build
    • 创建可执行文件:target/debug/hello_cargo 或 target\debug\hello_cargo.exe (Windows)
    • 运行可执行文件:./target/debug/hello_cargo 或 .\target\debug\hello_cargo.exe (Windows)
  • 第一次运行cargo build会在顶层目录生成cargo.lock文件
    • 该文件负责追踪项目依赖的精确版本
    • 不需要手动修改该文件

运行项目 cargo run

  • cargo run,编译代码+执行结果
    • 如果之前编译成功过,并且源码没有改变,那么就会直接运行二进制文件

cargo check

  • cargo check,检查代码,确保能通过编译,但是不产生任何可执行文件
  • cargo check 要比 cargo build 快得多
    • 编写代码的时候可以连续反复使用cargo check检查代码,提高效率

为发布构建

  • cargo build --release
    • 编译时会进行优化
      • 代码会运行得更快,但是编译时间更长
    • 会在target/release而不是target/debug生成可执行文件
  • 两种配置:
    • 一个开发
    • 一个正式发布

建议尽量使用Cargo

猜数游戏——一次猜测

游戏目标

  • 生成一个1-100之间的随机数
  • 提示玩家输入一个猜测
  • 猜完之后,程序会提示猜测太小了还是太大了
  • 如果猜测正确,那么打印一个庆祝信息,程序退出

代码实现

use std::io;  
use std::cmp::Ordering;  
use rand::Rng;  
  
fn main() {  
    println!("猜数!");  
    let secret_number = rand::thread_rng().gen_range(1, 101); // [1, 101)  
    // println!("神秘数字是:{}", secret_number);  
    loop {  
        println!("猜测一个数(1~100)");  
        let mut guess = String::new();  
        io::stdin().read_line(&mut guess).expect("无法读取行");  
        println!("你猜测的数是:{}", guess);  
        let guess: u32 = match guess.trim().parse() {  
            Ok(num) => num,  
            Err(_) => continue,  
        };  
        match guess.cmp(&secret_number) {  
            Ordering::Less => println!("你猜的数小了"),  
            Ordering::Greater => println!("你猜的数太大了"),  
            Ordering::Equal => {  
                println!("恭喜你,猜中了!!!");  
                break;            
			}  
        }  
    }  
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

通用的编程概念

变量与可变性

  • 声明变量使用let关键字
  • 默认情况下,变量是不可变的(Immutable)
  • 声明变量时,在变量前面加上mut关键字,就可以使变量可变
变量与常量
  • 常量(constant),常量在绑定值以后也是不可变的,但是它与不可变的变量有很多区别:
    • 不可以使用mut,常量永远都是不可变的
    • 声明常量使用const关键字,它的类型必须被标注
    • 常量可以在任何作用域内进行声明,包括全局作用域
    • 常量只可以绑定到常量表达式,无法绑定到函数的调用结果或只有在运行时才能计算出的值
  • 在程序运行期间,常量在其声明的作用域内一直有效
  • 命名规范:Rust里常量使用全大写字母,每个单词之间用下划线分开,例如:
    • MAX_POINT
  • 例子:const MAX_POINT: u32 = 100_000;
Shadowing(隐藏)
  • 可以使用相同的名字声明新的变量,新的变量就会shadow(隐藏)之前声明的同名变量
    • 在后续的代码中这个变量名代表的就是新的变量
  • shadow和把变量标记为mut是不一样的:
    • 如果不使用let关键字,那么重新给非mut的变量赋值会导致编译时错误
    • 而使用let声明的同名新变量,也是不可变的
    • 使用let声明的同名新变量,它的类型可以与之前不同

数据类型

  • 标量和复合类型
  • Rust是静态编译语言,在编译时必须知道所有变量的类型
    • 基于使用的值,编译器通常能够推断出它的具体类型
    • 但如果可能的类型比较多,就必须添加类型的标注,否则编译会报错
标量类型
  • 一个标量类型代表一个单个的值
  • Rust有4个主要的标量类型:
    • 整数类型
    • 浮点类型
    • 布尔类型
    • 字符类型
整数类型
  • 整数类型没有小数部分
  • 例如 u32 就是一个无符号的整数类型,占据32位的空间
  • 无符号整数类型以 u 开头
  • 有符号整数类型以 i 开头
  • Rust的整数类型:
LengthSignedUnsigned
8-biti8u8
16-biti16u16
32-biti32u32
64-biti64u64
128-biti128u128
archisizeusize
  • 有符号的范围: 2 n − 1 到 2 n − 1 − 1 2^n - 1 到 2^{n -1} - 1 2n12n11
  • 无符号范围: 0 到 2 n − 1 0 到 2^n - 1 02n1
isize 和 usize 类型
  • isize 和 usize 类型的位数由程序运行的计算机的架构所决定:
    • 如果是64位计算机,那就是64位的
  • 使用 isize 和 usize 的主要场景是对某种集合进行索引操作
整数字面值
Number LiteralsExanple
Decimal98_222
Hex0xff
Octal0o77
Binary0b1111_0000
Byte(u8 only)b’A’
  • 除了 byte 类型外,所有的数值字面值都允许使用类型后缀
    • 例如:57u8
  • 如果你不太清楚应该使用哪种类型,可以使用Rust相应的默认类型
  • 整数的默认类型就是i32
    • 总体上来说速度很快,即使在64位系统中
整数溢出
  • 例如:u8 的范围是0 ~ 255,如果你把一个u8变量的值设为256,那么:
    • 调试模式下编译:Rust会检查整数溢出,如果发生溢出,程序在运行时就会panic
    • 在发布模式下(–release)编译:Rust不会检查可能导致panic的整数溢出
      • 如果溢出发生:Rust会执行”环绕“操作:
        • 256变成0,257变成1…
        • 但程序不会panic
浮点类型
  • Rust有2种基础的浮点类型,也就是含有小数部分的类型
    • f32,32位,单精度
    • f64,64位,双精度
  • Rust 的浮点类型采用了 IEEE-754 标准来表述
  • f64 是默认类型,因为在现代CPU上 f64 和 f32 的速度差不多,而且精度更高
布尔类型
  • Rust的布尔类型也有2个值:truefalse
  • 一个字节大小
  • 符号是bool
字符类型
  • Rust语言中 char 类型被用来描述语言中最基础的单个字符
  • 字符类型的字面值使用单引号
  • 占用4字节大小
  • 是Unicode标量值,可以表示比ASCII多得多的字符内容:拼音、中日韩文、零长度空白符、emoji表情等
    • U+0000 到 U+D7FF
    • U+E000 到 U+10FFF
  • 但是Unicode中并没有”字符“的概念,所以直觉上认识的字符也许与Rust中的概念并不相符
let x := 'z';
let y : char = 'Z';
let z = '
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/702695?site
推荐阅读
相关标签