文章目录
一、案例一:读取输入打印出来
fn main() {
println!("Hello, world!");
let mut guess = String::new();
io::stdin().read_line(&mut guess).expect("error");
println!("你打印的数字是 {}",guess);
}
二、案例二:(引入新包)猜数字游戏
cargo build 安装新包
①引入随机数包
②引入随机库
③源码
use std::io; //需要引入库
use rand::Rng;
use std::cmp::Ordering;
fn main() {
let secret_num=rand::thread_rng().gen_range(1..101);
println!("请输入你的猜测数字!");
let mut guess = String::new();
io::stdin().read_line(&mut guess).expect("error");
let guess:i32 = guess.trim().parse().expect("请输出数字");
match guess.cmp(&secret_num){
Ordering::Less =>println!("猜小了"),
Ordering::Greater =>println!("猜大了"),
Ordering::Equal =>println!("猜对了"),
}
println!("你输入的数字是 {}",guess);
print!("秘密数字是:{}",secret_num);
}
三、案例三:循环猜测数字
use std::io; //需要引入库
use rand::Rng;
use std::cmp::Ordering;
fn main() {
let secret_num=rand::thread_rng().gen_range(1..101);
loop {
println!("请输入你的猜测数字!");
let mut guess = String::new();
io::stdin().read_line(&mut guess).expect("error");
let guess:i32 = match guess.trim().parse(){
Ok(num) =>num,
Err(_) =>continue,
};
match guess.cmp(&secret_num){
Ordering::Less =>println!("猜小了"),
Ordering::Greater =>println!("猜大了"),
Ordering::Equal =>{
println!("猜对了");
break;
},
}
println!("你输入的数字是 {}",guess);
print!("秘密数字是:{}",secret_num);
}
}
四、案例四:猜字游戏(彩色版本)
use std::io; //需要引入库
use rand::Rng;
use std::cmp::Ordering;
use colored::*;
fn main() {
let secret_num=rand::thread_rng().gen_range(1..101);
loop {
println!("请输入你的猜测数字!");
let mut guess = String::new();
io::stdin().read_line(&mut guess).expect("error");
let guess:i32 = match guess.trim().parse(){
Ok(num) =>num,
Err(_) =>continue,
};
match guess.cmp(&secret_num){
Ordering::Less =>println!("{}","太小了!".red()),
Ordering::Greater =>println!("{}","太大了!".red()),
Ordering::Equal =>{
println!("{}","猜对了!".green());
break;
},
}
println!("你输入的数字是 {}",guess);
print!("秘密数字是:{}",secret_num);
}
}
五、rust一些注意事项
1)声明变量默认是不可修改的
解决方法:(加mut关键词)
2)const定义常量,且必须加类型标注
const UC_NUM:u32 = 1000;
3)标量(scalar)和复合类型(compound)数据类型
①整数类型
debug超出正常范围就会panicked,release模式下会超过最大值得数转回最小值
②字符类型
③浮点数
④复合类型tuple
取元素方式:(tuple元素从0开始,如下所示)
①解构
②点标记
⑤数组vector
下面byte数组表示初始化了8元素的数组,数组全为0
六、函数
七、控制流程(if、else语句和while语句、for循环)
用条件控制流程:
while语句控制:
for循环:
或
或(用范围循环):
八、rustlings训练笔记(exercise目录)
安装步骤:
或是手工去github上git clone 下来安装:
命令:
rustlings watch //进入做题和批改模式
1)关于vscode的额外添加json配置
2)修正错误
(1)println缺少{}
的参数
(2)缺少let声明关键字
(3)变量得加上mut才能赋值
(4)x没有初始化赋值
得改成:
let x:i32=6;
(5)number一开始声明为字符串,得重新声明为整型
let number = 3;
(6)声明常量必须给出类型声明,下面的NUMBER没有类型
改成:
const NUMBER:i32 = 3;
(7)函数不用前向声明
(8)函数传参类型需要标注
(9)函数缺少返回值类型:
改成
fn sale_price(price:i32)->i32 {
...
}
(10)返回有分号要去掉,否则返回的是void类型
解决方法:
①去分号
②加上return
(11)被move的vec不能再调用了
解决方法:
①再拷贝一份数据(to_vec方法)
②传入引用数据,并且函数里面调用to_vec拷贝
③对原数组操作(原数组改为mut)
(12)不能对变量做两个可变引用
解决方法:
区分开作用域范围(提前结束参数y作用域)
九、rust三种常用内存管理方式
1)赋值构造string(不是浅拷贝,是move操作)
2)字符串作为函数参数传入就会被move
可以试着这样做:
或者返回出字符串:
3)对于整型变量是copy而不是move
4)利用引用解决字符串被move的问题
特点:允许使用,但是不获取所有权
若要修改原变量的值,加上mut:
5)不能对同一变量同时做两次可变引用(防止数据竞争Data Race)
6)变量若有不可变引用,就不能创建可变引用
除非不可变引用的作用域结束了:
7)生命周期结束的字符串不要取引用出来(数据得是有效的)
8)切片不会获取数据的所有权
获取切片示例:
使用举例(返回去除字符串里面空格的单词):
十、结构体
1)结构体简单构造
①初始化构建struct
或写个类似构造函数的函数:
或赋值构造函数:
2)元组结构体(没有字段名的结构体)
使用例子:
或者传入引用
3)debug模式下输出打印信息
#[derive(Debug)]
①{:?}打印信息
②{:#?}打印信息能打印更工整的信息
4)结构体里面附加函数area()
5)实例方法(必须传入自身)和关联函数
实力方法(必须传入自身结构体):
关联函数:
调用举例:
6)结构体部分的exercise习题总结
(1)实例化一个unit的结构体
(2)拷贝旧结构体,新增字段
(3)若参数错误则输出panic语句
十一、枚举和模式匹配
示例:
或者定义为字符串:
或者不同类型枚举:
1)枚举添加各种类型的值和取值
定义:
取值相加:
2)枚举匹配返回不同值
或可以循环嵌套枚举值:
3)Option表示可选,可传值也可以不传
里面的plus_one函数表示传入none就返回none,传入整数就返回Some(原来的数加1)
额外举例说明(若match匹配到了some(3)就打印,没匹配到就什么也不做):
4)枚举和模式匹配相关exercise习题
打到和下图的结构体一样:
编写对应的process函数:
十二、包和模块系统
cargo new xxx可以创建一个xxx的包
1)package包和crate的规则
举例说明:
①库形式的lib crate和二进制的mian crate
②若需要更多的二进制crate
bin目录中的每一个二进制文件都对应一个crate
2)模块modules讲解
(1)创建一个resturante的包,想要包中有一个库形式的crate
cargo new --lib resturante
(2)创建父模块和子模块、公共函数调用模块函数方法发
注意:子模块可以看到父模块关键字,若想要父看到子,需要加公立pub
公共函数:
①绝对路径
②相对路径
或另一种方法:(super可以访问父模块当中的函数server_order)
(3)模块函数、enum、struct可见性问题及解决方法
问题解决举例:(不是公立pub的)
修改为:
若需要修改struct里面的个别字段,则可以修改为:
举例枚举若不是pub的:
修改后为
(4)use简化引用路径
引用前:
引用后:
(5)若mod有冲突
①方法一:返回值不同
②方法二:起别名
(6)如何外部也能引用到hosting模块(加入pub关键字)
(7)如何引入外部包
①修改cargo.html
②引入rand到当前包当中
若引入包很多,则可以像下图一样:
这个可以简化为:(self为自身)
或:
(8)将模块定义移动到其他模块中去
原来的front_of_house模块:
移动后:
若还要挪动,则改为这样:
十三、常见集合(集合类型实例在堆上面)
1)动态数组vector
(1)定义数组
let a=[1,2,3];
let mut v:Vec<i32>=Vec::new();
let v2=vec![1,2,3];
(2)取值操作
匹配取值:
(3)遍历vec数组
若遍历来修改值,用*
取得值:
若vec存策划填表的数值:
2)utf-8编码文本(字符串,四种方法)
①初始化字符串
②添加字符
或
但是字符串不能通过下标访问:
打印阿斯克马和字符:
3)哈希map中存储键和关联值
①首先引入键值对
②创建并插入hashmap
③读取键值对数据
④插入多对为赋值香锅
entry为若有,则不插入,若无则插入
,entry返回键值对
下面的例子(统计字符串中字母的频率):
十四、错误处理
1)panic函数
①调用panic宏
②panic能看到调用的崩溃堆栈
2)可恢复错误处理
①先做个返回类型的枚举
②根究返回值判断
③引入ErrorKind对不同情况做分情况处理
(若打开失败则创建txt文件)
或者这样写:
或者:
3)错误传播(error propagation)(略)
用处:让调用方来处理错误,更加灵活