赞
踩
弱小和无知不是生存的障碍,傲慢才是
参考:
Rust 程序设计语言:https://rust.bootcss.com/
Rust程序设计语言重编版:http://shouce.jb51.net/rust-book-chinese/index.html
Runoob—Rust教程:https://www.runoob.com/rust/rust-tutorial.html
B站视频—Rust编程语言入门教程—杨旭:https://www.bilibili.com/video/BV1hp4y1k7SV?share_source=copy_web
边看B站视频边看笔记效果更佳
https://www.bilibili.com/video/BV1hp4y1k7SV?share_source=copy_web
1.2
节介绍了安装Rust
Windows + R cmd
rustc --version
Windows + R cmd
cargo --version
cargo new hello_cargo[项目名]
cargo build
cargo run
先编译后运行,如果编译过了,直接运行可执行二进制文件
修改源文件会重新编译
该二进制文件会在这个目录下
hello_cargo[项目名]\target\debug\hello_cargo.exe
cargo check
cargo check,检查代码确保能通过编译,但是不产生任何可执行文件
cargo check 要比 cargo build 快很多
编写代码可以连续反复使用cargo check 检查代码,提高效率
cargo build --release
两种构建方式一个为了开发,一个为了发布
mut 将 “不可变值” 变为 “可变值”
将a的值赋值给b let a = 1; let b = a; println!("{}",a);//输出宏的传参 println!("{}",b); 输出: 1 1 如果用另一种方式,先声明,再赋值 let a = 1; let b = 0; b = a; 会报错,因为所有的声明,默认是 immutable 不可变的 需要加 mut let a = 1; let mut b = 0; b = a; println!("{}",a); println!("{}",b); 注意:不能 let b ,所有的声明都要有初始值
io::stdin().read_line(&mut guess).expect("无法读取行");
io
下的stdin()
下的read_line()
方法:将用户一行输入放到字符串中,也就是 guess 中
read_line()
会返回io::Result<usize>
Result这个枚举类型中有两个"变体"(枚举类型中的固定值称作变体)
Ok 和 Err
返回的是 Ok,表示操作成功了,附加成功的字符串
如果返回的是 Err,表示操作失败了,附加失败的字符串以及报错信息
然后调用.expect()
方法
如果read_line()
返回的io::Result
实例的值是Ok,那么expect()
会提取Ok的附加值,作为结果返回给用户
如果read_line()
返回的io::Result
实例的值是Err,那么expect()
会把程序中断,并把传入的字符串信息显示出来
println!("你猜测的数是{}",guess);
{ } 占位符
use std::io;
fn main() {
println!("猜数");
let mut guess = String::new();
io::stdin().read_line(&mut guess).expect("无法读取行");
println!("你猜测的数是{}",guess);
}
Rust中的库 叫做 crate
官方的库
https://crates.io/
在Cargo.toml 文件中引入
[dependencies]
rand = "^0.3.14"
^表示任何与这个版本公共API兼容的版本都可以
在VsCode中,引入包后运行这个命令会帮你构建一些
Ctrl + Shift + P
>rust
Rust: Start the Rust server
如果Cargo.toml
文件引入的
[dependencies]
rand = "0.3.14"
那么在你第一次构建的时候
会在Cargo.lock
这个文件写入所有依赖项的版本
并且会写入最新版本
比如说 在Cargo.toml
引入的版本rand = "0.3.14"
那么会在Cargo.lock
写入0.3版本的的最新小版本
[[package]]
name = "guess_number"
version = "0.1.0"
dependencies = [
"rand 0.3.23",
]
再次构建的时候就会先查看Cargo.lock
这个文件里面的版本
use rand::Rng;
这个包是一个trait
你可以把它想成接口
而在代码中引入包相当于一个类实现一个接口
所以如果你引入,而不用就会报错
gen_range()
方法gen_range(1,101)
会在 [ 1 , 101 )之间生成随机数,1-100之间包含1和100(左闭右开 )
use std::io; use rand::Rng; fn main() { println!("猜数!!!"); let secret_number = rand::thread_rng().gen_range(1,101); println!("生成随机数:{}",secret_number); println!("请输入你要猜的数字:"); let mut guess = String::new(); io::stdin().read_line(&mut guess).expect("无法读取行"); println!("你猜测的数是{}",guess); }
Ordering有三个变体Less
、Greater
、Equal
guess.cmp(&secret_number)
是用 guess 和 secret_number 进行比较,这个方法会返回一个Ordering
match
表达式,可以让我们根据cmp()
方法返回的Ordering的值来决定我们下一步做什么
一个match
表达式是由多个手臂(arm)或者叫分支组成的,有点像switch
每个手臂含有一个用于匹配的模式这里就是Less
、Greater
、Equal
如果match
后面紧跟着的值与某一个 arm 的模式匹配,那么就会执行这个 arm 里面的代码
match
是按从上到下的顺序进行匹配的
guess.cmp(&secret_number)
中的 guess 你输入的是字符串,而 secret_number 是随机的整数,进行比较会报错
因此要把 guess 变为整数进行比较
let guess: u32 = guess.trim().parse().expect("请输入整数");
guess.trim()
会删除空格、tab、以及回车(输入时候按回车就会有 \n 输入)
parse()
会把输入的字符串解析,有i32
u32
i64
,我们这里选择解析成u32
let guess: u32
在变量后面加 : u32
use std::io; use rand::Rng; use std::cmp::Ordering; fn main() { println!("猜数!!!"); let secret_number = rand::thread_rng().gen_range(1,101); println!("生成随机数:{}",secret_number); println!("请输入你要猜的数字:"); let mut guess = String::new(); io::stdin().read_line(&mut guess).expect("无法读取行"); println!("你猜测的数是{}",guess); let guess: u32 = guess.trim().parse().expect("请输入整数"); match guess.cmp(&secret_number){ Ordering::Less => println!("太小了"), Ordering::Greater => println!("太大了"), Ordering::Equal => println!("猜对了"), } }
把下面的代码注释掉,默认是i32
当把 guess 字符串解析为u32
时,secret_number也变为了u32
loop{}
break;
结束全部循环
continue;
结束本次循环
原本的程序
let guess: u32 = guess.trim().parse().expect("请输入整数");
如果输入字符串,会直接抛出异常中止程序
我们想要遇到异常,不结束程序,并且告诉他输入数字
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => {
println!("输入数字!");
continue;
}
};
guess.trim().parse()
的返回值是 Result
Result 有两个变体 Ok 和 Err
Ok 的情况下,正常赋值
Err 的情况下,告诉用户输入数字,并且结束本次循环(然后继续从头走循环)
use std::io; use rand::Rng; use std::cmp::Ordering; fn main() { println!("猜数!!!"); let secret_number = rand::thread_rng().gen_range(1,101); println!("生成随机数:{}",secret_number); loop{ println!("请输入你要猜的数字:"); 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; } } } }
let
关键字mut
,就可使变量可变 Ctrl+左键 查看示例常量(constant),常量在绑定值以后也是不可变的,但它与不可变的变量有很多区别
不可以使用 mut ,常量永远都是不可变的
声明常量使用 const 关键字,它的类型必须被标注
常量可以在任何作用域内进行声明,包括全局作用域
在程序运行期间,常量在其声明的作用域内一直有效,因此可以作为不同代码之间共享值
const MAX_POINTS: u32 = 10_0000;
fn main() {
const MAX_POINTS: u32 = 10_0000;
}
常量只可以绑定到常量表达式,无法绑定到函数的调用结果或只能在运行时才能计算的值(就是在编译期就确定了)
命名规范:Rust 里常量使用全大写字母,每个单词之间用下划线分开,例如:
const MAX_POINTS: u32 = 10_0000
数字增加下划线只是为了增加可读性
可以使用相同的名字声明新的变量,新的变量就会 shadow(隐藏) 之前声明的同名变量
在后续的代码中这个变量名就是新的变量
shadow :
fn main() {
let a = 2;
let a = a + 1;
let a = a * 3;
println!("The value a is :{}",a);
}
mut
:
fn main() {
let mut a = 2;
a = a + 1;
a = a * 3;
println!("The value a is :{}",a);
}
但是shadow 和把变量标记为
mut
是不一样的
使用let
声明的同名新变量,也是不可变的
使用let
声明的同名新变量,它的类型可以与之前不同
shadow :
fn main() {
let str = " ";
let str = str.len();
println!("长度{}",str);
}
mut
:
fn main() {
let mut str = " ";
str = str.len();//报错:把一个整数赋给字符串
println!("长度{}",str);
}
Rust 是静态编译语言,在编译时必须知道所有变量的类型
基于使用的值,编译器通常能够推断出它的具体类型 Ctrl+左键 查看示例
但如果可能的值比较多(例如把 String
转成整数的 parse()
方法),就必须添加类型的标注,否则编译会报错
let str: u32 = "2".parse().expect("Not a number");
一个标量类型代表一个单个的值
Rust 有四个主要的标量类型:
u32
就是一个无符号的整数类型,占据 32 位的空间i:有符号整数范围
[
−
(
2
n
−
1
)
,
2
n
−
1
−
1
]
[-(2^n - 1) , 2^{n-1} - 1]
[−(2n−1),2n−1−1]
u:无符号整数范围
[ 0 , 2 n − 1 − 1 ] [0,2^{n-1} - 1] [0,2n−1−1]
如表格所示,每种都分 i 和 u 以及固定的位数
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类型
isize 和 usize类型的位数由程序运行的计算机的架构决定:
如果是 64 位计算机,那就是 64 位
…
使用 isize 和 usize 的主要场景是对某种集合进行索引操作(不常见)
为了便于辨识整型字面值,可以在字面值中加入 _ 用作数字之间的分隔,如:1_000_000,_ 所起的作用仅仅是方面代码的阅读,它与1000000表示的相同的数值;另外除了字节字面值(即以0,1序列表示的数值),其他类型的整型字面值都可以加上类型说明符作为后缀以标识数值类型,如:255u8
, 1024i64
或者1024_i64
等。
let a = 255u8
一个数字,可以采用不同的进制表示,如十进制,十六进制,八进制和是二进制等。区分这些不同进制的数的方式是根据字面值所带的前缀,如下表:
字面值类型 | 示例 |
---|---|
二进制 | 0b100_0001 |
八进制 | 0o101 //零欧 |
十进制 | 65 |
十六进制 | 0x41 |
字节(只能是u8) | b’A’ |
如果你不太清楚使用哪种数据类型,整数默认类型就是i32
例如:u8
的范围是 0 ~ 255,如果你把一个u8
变量的值设称 256,就会发生整数溢出:
这分为两种情况
调试模式下编译:Rust 会检查整数溢出,如果发生溢出,程序在运行时就会panic(恐慌)
发布模式下(–release)编译:Rust 不会检查可能导致 panic 的整数溢出
如果溢出发生:Rust 会执行“环绕”操作
256变为0,257变为1
但程序不会 panic浮点类型
Rust 有两种基础的浮点类型
f32
,32位,单精度
f64
,64位,双精度
let a = 1.0;//f64
let a :f32 = 1.0;//f32
Rust 的浮点类型使用了 IEEE-754 标准来表述
默认会使用 f64
类型
加减乘除余
跟其他语言一样,不多赘述
let sum = 5 + 10;
let difference = 97.8 - 24.1;
let producet = 4 * 30;
let quotient = 56.7 / 32.1;
let reminder = 54 % 5;
true
、false
bool
let t = true;
let f :bool = false;
Rust 语言中 char
类型被用来描述语言中最基础的单个字符
字符类型的字面值使用单引号
占用 4 个字节大小 (1个字节 = 1 byte = 8 位 = 8 bit 比特 = 8 个 0,1)
是 Unicode 标量值,可以表示比 ASCⅡ 多得多的字符内容:拼音,中日韩文,零长度空白字符,emoji表情等
范围:
U+0000 ~ U+D7FF
U+E000 ~ U+10FFFF
但 Unicode 中并没有 “字符” 的概念,所以直觉上认为的字符也许与 Rust 中的概念并不相符
请注意字符类型是单引号
如果let b :char = "₦"
这样声明会报错
let a = 'n';
let b :char = '₦';
let c = '声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/702724
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。