根据《精通Rust(第二版)》的顺序进行记录
因为博主总在上课的时候困成狗,所以试图记录一下防止睡着,笔记可能看起来个人风格太强,也许还有未完成的部分,如果有时间的话改成阅读性更强的博客吧
也欢迎看到这篇笔记的人督促博主不要上课睡觉23333
在powershell创建新项目: $cargo new [项目名]
编译源文件: rustc XX.rs
执行直接.\就可以
about Copy Opration:
// about Copy Opration:
let x: i32 =5;
let y=x;
println!("The value of x is{:?}",x);
println!("The value of y is {:?}",y);
// about Move Opration:
let x=String::from("hello");
let y=x;
println!("The value of x is{:?}",x);//会报错
println!("The value of y is {:?}",y);
let y: &String=&x; //不会报错
// immutable(不可改的) Borrow
let x=String::from("hello");
x.push_str(string:"world"); //会报错,因为是不可改的引用
let mut x=String::from("hello");
let y=&mut x;
println!("The value of x is{:?}",x);
println!("The value of y is {:?}",y); //会报错,不能出现两个可修改的指针
//value is deallocated
let y: &String;
{
let mut x: String=String::from("hello");
y=&x;
}
println!("The value of y is {:?}",y); //会报错,因为生存周期不对
栈内存与堆内存的区别:确定大小vs内存动态变化
Owner原则:一个值只有一个所有者,一个值在任一时刻都只有一个拥有者,当所有者离开后值自动丢弃
出现数据竞争的三种行为:两个指针同时访问同一数据,至少有一个指针用于写入数据,没有使用任何机制来同步对数据的访问
1.谁都有系列:bool
,char
,int
(分isize
/usize
),f32
,f64
2.字符系列:常用&str
3.数组系列:固定大小数组[T;N]
,T为元素类型,N为元素数目;
动态大小的连续序列[T]
,T为类型;
有限序列(T,U,...)
,T和U类型可以不同.
4.函数类型fn(i32)->32
:接收i32
类型参数,返回i32
类型参数
关键词let
声明变量,默认是不可变,如果想改变变量值,添加关键词mut
。
打印的时候一般用{}
表示,也可以用占位符{:?}
表示没有清晰面向用户的输出类型。
保存在一个变量中,或作为参数传给其他函数的匿名函数。例:
let doubler=|x| x*2;
let twice=doubler(5);
构造方法举例:
let question = "How are you ?"; // a &str type
let person: String = "Bob".to_string();
let namaste = String::from("नमस्ते"); // unicodes yay!
区别:String类型在堆上分配,&str类型通常为指向字符串的指针。
let mut s1=String::new(); //length:5 cap:8
s1.push_str("hello");
let s1: &str="hello"; //length:5 cap:5
例子:
fn main(){
let res=false;
if res{
println!("indeed");
}else{
println!("Well,you should try Rust!");
}
// 也可以用来定义
let result=if 1==2{
"Wait,what?"
}else{
"Rust makes sense."
}
}
switch语句的简化版,也可以为变量赋值。例:
let status=req_status();
match status{
200 => println!("Success");
404 => println!("Not Found");
other =>{//other也可以用下划线_代替
println!("Request failed woth");
}
}
loop:无限循环
loop循环代码块可以直接使用名称标记,使用break
可以退出指定代码块的循环。
示例:
fn main(){
let mut x=1024;
loop{
if x<0{
break;
}
println!("{} more runs to go,"x);
x-=1;
}
//用代码块标记循环:
let mut resulr=0;
'increment:loop{
if result==a{
let mut dec=b;
'decrement:loop{
if dec==0{
// 直接退出increment的循环
break 'increment;
}else{
result-=1;
dec-=1;
}
}
}else{
result+=1;
}
}
}
while循环示例
while x>0{
println!("{} more runs to go", x);
x-=1;
}
for循环示例
for i in 0..10{ //从1打印到9
print!("{}",i);
}
for i in 0..=10{//从1打印到10
print!("{}",i);
}
1.结构体struct
struct Color(u8,u8,u8);
fn main(){
let white=Color(255,255,255); //结构体声明
let red=white.0;//可以用index赋值
let Color(r,g,b)=orange;//对结构体解构
println!("R: {}, G: {}, B: {} (orange)", r, g, b);
}
使用关键词impl
对结构定义构造函数和其他方法。举例:
struct Player {
name: String,
iq: u8,
friends: u8
}
impl Player {
fn with_name(name: &str) -> Player {//构造函数
Player {
name: name.to_string(),
iq: 100,
friends: 100
}
}
fn get_friends(&self) -> u8 {
self.friends
}
fn set_friends(&mut self, count: u8) {
self.friends = count;
}
}
2.枚举类型enum
由于enum不是产常见的数据类型,若想打印,要加入声明#[derive(Debug)]
,并使用{:?}
形式输出。
enum
可以为不同的变体建模,变体可以包含/不包含数据。包含的数据可以是任何基元类型、结构体、枚举类型。
枚举在栈上创建,所以需要预先定义大小。
P.S.我们同样可以使用impl
对枚举类型定义方法,思路是对多种枚举量封装不同的方法。
1.数组(array)
声明方式:ler 变量名:[T;N]=[元素,元素,元素];
T表示元素,N表示元素数目。
2.元组(tuple)
3.项目列表(vector)
标准库提供的动态集合类型。举例:
let mut numbers_vec: Vec=Vec::new();
let mut vec_with_marco=vec![1]; //宏创建的声明方法
// 添加元素和删除元素
numbers_vec.push(1);
let _=vec_with_marco.pop();
4.键值对(map)
let mut fruits=HashMap::new();
fruits.insert("apple",3);
fruits.insert("orange",2);
fruits.remove("orange");
5.切片(slice)
let mut numbers:[u8;4]=[1,2,3,4];
let all: &[u8]=&numbers[..]; //全部切片
let first_two: &mut [u8] = &mut numbers[0..2]; //取前两个
let last_two: &mut [u8] = &mut numbers[..2]; //取后两个
6.关于胖指针的概念:
胖指针包含指向元素元素多少的信息…
7.迭代器
高效访问集合元素的方法。例:
let mut numbers: [u8;4]=[1,2,3,4];
let num = &numbers[..].iter().next();
println!("The first number: {:?}", num);
//打印结果为Some(1)
rust对集合里元素包装了一下,所以会打印出这样的结果。