看一看Rust,记录下自己笔记:安装及变量类型

第一章: 认识Rust

编程环境

官网有着详细的描述的命令执行步骤

windows 推荐使用 ubuntu 子 环境执行 rust 环境搭建,

idea 插件也支持 使用wsl 环境了,这个非常的方便

设置 path 环境变量

以下是linux 的配置过程

  1. 加入环境变量

    export PATH=“ H O M E / . c a r g o / b i n : HOME/.cargo/bin: HOME/.cargo/bin:PATH”

  2. 配置生效

    source .bash_profile

更新rust

rustup update

卸载 rust

rustup self uninstall

Hello Rust
fn main(){
	println!("hello Rust!");
}
  1. 编译

    rustc main.rs

  2. 运行

    ./main

Hello Cargo

Rust 提供的构建工具和包管理器Cargo,

cargo new # 新建项目
cargo build # 编译项目
cargo check # 检查报告项目中的错误,但不编译任何文件
cargo run   # 编译运行项目
cargo test  # 测试项目
cargo doc   # 构建项目文档
cargo publish  # 发布库到 crates.io
cargo clean  #  移除项目的target文件夹递归
cargo update  # 更新所有依赖库

cargo new project_name 创建可执行的二进制程序

cargo new project_name --lib 创建库

cargo build --release 在发布前,优化编译项目,

第二章: 变量与数据类型

  1. std::collections 提供了4中通用的容器类型,: 包含 8种 数据结构
    1. 动态数组 分为 : 普通动态数组Vec 和 双端队列VecDeque
    2. 映射 分为 HashMap
    3. 字符串 包括 String等类型

变量和可变性

本质上是一种绑定语义,即将一个变量名与一个值绑定在一起。

另一个不同点是 : 变量默认是不可改变的。

变量声明

  1. 变量遵循先声明后使用

  2. 变量名: 必须字母、数组、下划线组成,字母却分大小写,且不可以以数字开头,也不能只有下划线

fn main() {
    let x: i8 = 1;
    let x = 1; // 等价于  let x:i32 = 1;
}

变量的可变性

对不可变变量二次赋值

let 声明的变量默认是不可变的,第一次赋值后不能再通过再次赋值来改变值,

如果赋值,会报错!!!

对可变变量二次赋值

可以 对 变量进行 mut 修饰,可以进行复制

fn main() {
    let mut c = 3;
    c = 5;
    println!("x : {}", c)
}

Rust 语言安全性的一大体现

变量遮蔽

Rust 容许在同一个代码块中声明一个与之前已声明变量同名的新变量,新变量会遮蔽之前的变量,这样无法再去访问前一个同名的变量。——————变量遮蔽

fn main() {
    let x = 3;
    let x = x + 2;
    let x = x * 2;
    println!("x : {}", x);

    let x = "Hello Rust";
    println!("x:{}", x)
}
//x : 10
//x:Hello Rust

虽然是同样的变量名,但是不具有覆盖的作用,还是本质上的两个变量,只是恰巧与前一个变量名相同而已

常量

常量是指 绑定到一个表示符且不容许改变的值,一旦定义后就没有任何方法能改变其值了。

fn main() {
    const MAX_NUM: u32 = 1024;
}

常量与不可变量的区别的是

  1. 常量名通常是全局变量,大写字母,且必须指定常量的数据类型
  2. 常量声明使用const关键字,且必须注明值的类型
  3. 通过变量遮蔽的方式可以让不可变量改变,但是常量不可以遮蔽,不能重复定义。
  4. 常量可以在任何作用域中声明,包括全局作用域。
  5. 常量只能被赋值为常量表达式或数学表达式,不能是函数返回值,或是其他在运行时才能确定的值。

基本数据类型

数据类型是作为静态编译语言的基础。

基本数据类型有: 整数类型、浮点数类型、布尔类型、字符类型、范围类型。

整数类型

整数是指没有小数点的数字。

根据有无符号,分为 有符号整数,无符号整数。

长度有符号无符号
8位i8u8
16位i16u16
32位i32u32
64位i64u64
128位i128u128
archisizeusize
 fn main() {
    let integer1: u32 = 17; // 类型声明
    let integer2 = 17u32; //类型后缀声明
    let integer3 = 17; // 默认i32 类型
    let integer4: u32 = 0b10001; // 二进制
    let integer5: u32 = 0o21; // 八进制
    let integer6: u32 = 0x11; // 十六进制
    let integer7 = 50_000; // 数字可读性分隔符_
}

浮点数类型

浮点数为带小数点数组,

默认类型为 f64

  1. f32: 单精度浮点数,小数点后面至少有6位有效数字
  2. f64: 双精度浮点数,小数点后面至少有15位有效数字
fn main() {
    let float1: f32 = 1.1; // 类型声明
    let float2 = 2.2f32; // 类型后缀声明
    let float3 = 3.3; // 默认f64类型
    let float4 = 11_000.555_001; // 数字可读性分隔符
}

布尔类型 及 字符类型

let t: bool = true; //显示声明
let t = false; // 隐式声明


// Rust 是UTF-8 作为底层的编码,每个字符占4个字节
let z = 'z';
let zz =Z';
let heart_eyed_cat = '猫头头像'

范围类型

常用来生成从一个整数开始另一个整数结束的整数序列,有左闭右开和全闭两种形式

fn main() {
    print!("(1..5):");
    for i in 1..5 {
        print!("{}", i)
    }

    println!();

    // rev 顺序反转
    print!("(1..=5).rev :");
    for i in (1..=5).rev() {
        print!("{}", i)
    }

    println!();

    let sum: i32 = (1..=5).sum();
    println!("sum :{}", sum)
}

//(1..5):1234
//(1..=5).rev :54321
//sum :15

复合数据类型

元组、数组、结构体和枚举等

元组类型

由一个或多个类型的元组组合成的复合类型,使用小括号()把所有元素放在一起。元素类型可以不一致。但是元组长度在初始化固定死,不能再改变

fn main() {
    let tup1: (i8, f32, bool) = (-10, 7.7, false);
    let tup2 = (7.7, (false, 10));
    let tup3 = (100,);

    println!("{}, {}", tup1.0, (tup2.1).1);
    println!("{}", tup3.0);

    let (x, y, z) = tup1;
    println!("x : {}, y : {} , z: {}   ", x, y, z)
}
//-10, 10
//100
//x : -10, y : 7.7 , z: false

数组类型

与元组的类型区别:

  1. 类型必须保持一致

一样的是,长度也不可以发生变化

fn main() {
    let arr1: [i32; 5] = [1, 2, 3, 4, 5]; // 第一种声明方式,确定类型和长度和初始值
    let arr2 = [1, 2, 3, 4, 5]; // 第二种声明方式,隐式判断数据类型和数组长度
    let arr3: [i32; 5] = [1; 5]; // 等价于 [1,1,1,1,1] 使用默认值初始化
    let arr4 = [1; 5]; // 与arr3 含义一样

    println!("{:?}", arr1);
    println!("{:?}", arr2);
    println!("{:?}", arr3);
    println!("{:?}", arr4);
}

//[1, 2, 3, 4, 5]
//[1, 2, 3, 4, 5]
//[1, 1, 1, 1, 1]
//[1, 1, 1, 1, 1]

结构体类型

是自定义数据类型,通过struct 关键字加自定义命名,

struct ListNode {
	val: i32,
    next: Option<Box<ListNode>>,
}

例子

struct Student {
    name: &'static str, // 1. & 以后都是属于类型的定义
    score: i32,
}

fn main() {
    let score = 59;
    let username = "zhangsan";
    let mut student = Student {
        score,         // 2. 变量名与结构体里面的字段名一样,可以忽略对应
        name: username,
    };

    student.score = 60;   // 3.  结构体实例默认是不可变的,且不容许只江某个字段标记为可变,如果要修改结构体实例必须在创建实例前就声明为可变的
    println!("name:{} , score : {}  ", student.name, student.score);


    let student2 = Student{
        name:"lisi",
        ..student  // 4. 自动通过名称对应未显示设置值的字段以传入实例进行更新
    };
    println!("name:{} , score : {}  ", student.name, student.score);
}

//name:zhangsan , score : 60  
//name:zhangsan , score : 60
元组结构体

字段只有类型,没有名称

fn main() {
    struct Color(i32, i32, i32);

    let black = Color(0, 0, 0);
}
单元结构体

单元结构体是指没有任何字段的结构体,一般只用于特定的场景

struct Solution;

枚举类型

是一个自定义数据类型,通过enum关键字加自定义命名来定义。

使用 枚举名::枚举值 访问值

fn main() {
    
    let color_no_param = ColorNoParm::Red;
    match color_no_param {
        ColorNoParm::Red => println!("{:?}", ColorNoParm::Red),
        ColorNoParm::Yellow => println!("{:?}", ColorNoParm::Yellow),
        ColorNoParm::Blue => Blue!("{:?}", ColorNoParm::Blue),
    }
    
}
// Red

枚举内容带有String类型参数,类似于函数调用

#[derive(Debug)]
enum ColorParm {
    Red(String),
    Yellow(String),
    Blue(String),
}

fn main() {
    println!("{:?}",ColorParm::Blue(String::from("blue")))
}

//Blue("blue")

容器类型

std::collections 提供了4 种通用的容器类型

类型容器描述
线性序列Vec连续存储的可变长数组
VecDeque连续存储的可变长双端队列
LinkedList非连续存储的双向链表
键值对HashMap<K,V>hashMap
BTreeMap<K,V>B树 的有序键值对
结合HashSet无序集合
BTreeSet有序结合
优先队列BinaryHeap二叉堆的优先队列

Vec

Vec 是一种动态可变长的数组,即在运行时可增长或者缩短数组的长度。,

内存为连续内存快用于存储,只能存储相同类型元素。

fn main() {
    let mut v: Vec<i32> = Vec::new();// 创建空的动态数组
    let mut v1: Vec<i32> = Vec::with_capacity(10); // 创建指定容量的动态数组
    let mut v2 = Vec![1,2,3];// Vec! 创建动态数组并且进行初始化,,并且会根据初始值自动推断动态数组的元素类型


    //  添加
    let mut v3: Vec<i32> = Vec::new();
    v3.push(1);
    v3.push(2);
    v3.push(3);

    // 修改
    v3[1] = 5;

    // 删除

    // 1.删除最后一个
    v3.pop();

    // 2. 删除并返回指定索引的元素
    let temp = v3.remove(1);


    // 访问
    // 1. 索引方式直接访问
    let tem = v3[1];
    // 2. get 方法访问,可避免索引越界
    let tm1 = v.get(1); // 如果该索引的值不存在,返回None


    // 遍历所有元素
    for i in v3 {
        println!(i)
    }
    // 遍历获取每一个元素的可变引用
    for i in &mut v3 {
        *i += 50;  // 使用* 来追踪和修改元素值
        println!(i)
    }
}

VecDeque

双端队列是一种具有栈和队列特征的数据结构,

适合于只能在队列两端进行添加或删除元素操作的应用场景。

fn main() {
    // 1. 创建
    let mut v1: VecDeque<u32> = VecDeque::new(); // 创建空的队列
    let mut v2: VecDeque<u32> = VecDeque::with_capacity(10); // 创建同时指定长度

    // 2 修改
    v1.push_back(10); // 添加到末尾
    v1.push_front(1);// 添加到开头

    // 3. 修改
    v1[1]= 4;// 指定索引修改

    // 4. 删除元素两种方式 ,
    // 两者都会返回Option类型的值Some(2)
    v1.pop_back();
    v1.pop_front();
    // 使用remove方法删除,并返回指定索引的元素
    v1.remove(1) ;// 如果索引为空,返回None
    
    
    // 5 访问
    // 直接指定索引访问元素
    v1[0];
    
    // get 方法返回元素
    v1.get(1);
}

HashMap

hash 不容许有相同的key,

fn main() {
    // 1. 创建
    let mut map: HashMap<&str, i32> = HashMap::new();//
    let mut map1: HashMap<&str, i32> = HashMap::with_capacity(10);

    // 2. 修改
    // insert 插入数据
    let zhangsan1 = map.insert("zhagnsan",85); // 如果存在,则服务覆盖,不存在则是插入
    
    // 检查键是否有对应值,只进行没有值的操作 entry,or_insert
    // entry 
    map.entry("zhangsan" ).or_insert(97);
    
    // 修改值
    for (_,val ) in map.iter_mut(){
        *val += 2; // 每一个value + 2
    }
    
    // 删除键值对,返回要删除的值,,没有返回None
    map.remove("zhangsan");
    
    // 直接key 获取 或者 get 方法获取
}

字符串

字符串本身也是一种特殊容器类型,是有零个或多个字符组成的有限序列。

字符串创建
  1. 固定长度的字符串字面量str
  2. 可变长度字符串对象String
fn main() {
    // &str 的创建
    let s1 = "Hello Rust";
    let s12 = String::from("hello Rsut");
    let s13 = s12.as_str();
    
     
    // 对象String 的创建
    let mut s = String::new();

    let s = String::from("hello reust");
    let str = "hello, Rust";
    let s = str.to_string(); // 转换
}
字符串修改
fn main() {
    let s1 = "Hello Rust";
    let s12 = String::from("hello Rsut");
    let s13 = s12.as_str();

    // 对象String 的创建
    let mut s = String::new();

    let s = String::from("hello reust");
    let str = "hello, Rust";
    let mut s2 = str.to_string(); // 转换


    // 修改

    //  1. 尾部添加
    s2.push('R');
    s2.push_str("RR");

    //  2. 插入
    s2.insert(5, ',');
    s2.insert_str(5, ",,");

    // 3. 使用 + or += 拼接
    s2 += s1;

    // 4. 使用format! 连接字符串
    let s = format!("{}-{}-{}", s1, s2, s13);

    // 5. 使用replace  和  replacen 替换
    s2.replace("aa", "33");
    s2.replacen("aa", "55", 1); // 替换数量

    // 6 使用pop,remove,truncate, clear 删除字符
    s2.pop();// 删除最后一个字符 返回Option<Char>
    s2.remove(1);//删除指定索引字符
    s2.truncate(9); // 删除字符串中从指定位置开始到结尾的全部字符
    s2.clear();//删除全部字符

    // 访问
    // 长度
    s2.len();


    // 迭代器访问字符串类型
    let bytes = s2.bytes();
    for b in bytes {
        print!("{} |", b)
    }
    for c in s2.chars() {
        println!(c)
    }
}

字面量和运算符

字面量: 由文字、数字或符号构成的值,他只能作为等号右边的值出现

运算符与其他语言一样

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值