Rust语言与内存安全设计(一)——入门介绍

Rust语言与内存安全设计(一)——入门介绍

根据《精通Rust(第二版)》的顺序进行记录
因为博主总在上课的时候困成狗,所以试图记录一下防止睡着,笔记可能看起来个人风格太强,也许还有未完成的部分,如果有时间的话改成阅读性更强的博客吧
也欢迎看到这篇笔记的人督促博主不要上课睡觉23333

2002.9.1 入门介绍

一些基本命令行

在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); //会报错,因为生存周期不对

关于Rust的内存安全性:

栈内存与堆内存的区别:确定大小vs内存动态变化

Owner原则:一个值只有一个所有者,一个值在任一时刻都只有一个拥有者,当所有者离开后值自动丢弃

出现数据竞争的三种行为:两个指针同时访问同一数据,至少有一个指针用于写入数据,没有使用任何机制来同步对数据的访问


2022.9.8

常见基元类型:

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."
    }
}

match表达式

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对枚举类型定义方法,思路是对多种枚举量封装不同的方法。

module、import和use语句

关于集合

1.数组(array)

声明方式:ler 变量名:[T;N]=[元素,元素,元素];
T表示元素,N表示元素数目。

2.元组(tuple)

3.项目列表(vector)

标准库提供的动态集合类型。举例:

let mut numbers_vec: Vec<u8>=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对集合里元素包装了一下,所以会打印出这样的结果。

猜你喜欢

转载自blog.csdn.net/weixin_60482947/article/details/127632150