Rust基础知识

48 阅读6分钟

直接上代码:

const MAX_COUNT: i32 = 100000; 
use std::collections::HashMap;
use std::fs::File;
fn main() { 
let name: type = 初始值
// 1. 定义不可变的变量(可变性)
let a = 1;
println!("a = {}", a);
// 2.定义可变的变量 mut(不可变性)
let mut b = 3;     
b = 2;
println!("b = {}", b);
// 3、隐藏性,后同名的会把前面的隐藏掉
let b = 1.1;
println!("b = {}",b);

// 4、常量
println!("MAX_COUNT = {}",MAX_COUNT);

// 布尔类型的值
let bol = true;
println!("bol = {}",bol);

// char是32位的,c++是8位的
let a = '为';

// 数字类型的 i8, i16, i32, i64, u8, u16, u32, f32, f64
let cha = 1.1;
let flo = 0.00009;
let i = -12;

// 自适应类型的值(随平台而定) isize usize


// 数组 【type; size】
let arr = [1,2,3];
let arr1: [u32; 5] = [1,2,3,4,5];

fn show(arr:[u32;3]) {
    for i in &arr {
        println!("{}", i);
    }
}
show(arr);

// 元组
let yanzu: (i32, f32, char) = (-3, 3.67, '好');
let yanzu = (-3, 3.67, '好');
println!("{}", yanzu.0);
let (x, y, u) = yanzu;
println!("{}", x);

// 函数 (不可以返回一个引用 )
fn other_fn () {
    println!("this is function");
}
other_fn();

fn other_fn1 (a: i32, b:u32) {
    println!("a ={}, {}",a,b);
}
other_fn1(12,12);

fn other_fn2 (a: i32, b:i32) -> i32{
    println!("a ={}, {}",a,b);
    return a+b; // a+b
}
let b = other_fn2(12,12);
println!("{}",b);

// 注释 双斜杠

// 控制流 if else
fn ies () {
    if true {
        println!("if");
    } else {
        println!("else");
    }
}
ies();
// let 中使用if
let condiction = true;
let y = if condiction { // if 与else 中必须为同一类型
    5
} else {
    10
};
println!("y = {}", y);

// loop 无限运行 break中断
let mut counter = 0;
loop {
    println!("loop is {}", counter);
    if counter == 12 {
        break;
    }
    counter = counter + 1;
}
let reault = loop {
    counter  += 1;
    if counter == 20 {
        break counter * 2;
    }
};
println!("reault = {}",reault);

//  while
let mut i = 1;
while i != 10 {
    i += 1;
    println!("while");
}

// 字符串
let str = String::from("hello");
println!("{}", str);

// 引用 和c++一样的 用法&,让我们创建一个指向值的应用,但是并不拥有它,因为不拥有这个值,所以,当引用离开其指向的作用域后也不会被丢弃
/**
 * 但是并不拥有它
 * 如果想改变这个引用,就要“借用” ==> &mut,
 * let r1 = &s1; 引用
 * let r2 = &s1; 引用
 * let r3 = &mut s1; 可变引用
 * 在下面使用r1,r2会报错,因为r1,r2可能不是你想要的结果
 * 
 */
// 总结:在任意给定时间,要么只能有一个可变引用,要么只能有多个不可变引用(有了可变引用之后,不能再有不可变引用);引用必须有效
fn calute (s: &String) -> usize {
    s.len()
}

let len = calute(&str); // 注意传入的是一个引用 &+变量名
println!("{}", len);
println!("{}", str); // 由于上面使用的引用,所以它的作用域后也不会被丢弃,否则报错

// slice
// 1、字符串中的slice,表示一部分值的引用。
// 2、字面值就是slice
// 3、其他类型slice
let str1 = String::from("hello");
let h = &str1[0..3]; // 0-3 前闭后开
let h1 = &str1[0..=3]; // 0-3 前闭后闭
let h2 = &str1[..=3]; // 起始不写从头开始


println!("{}, {}, {}", h, h1, h2);
// 结构体
// 1、定义结构体
    struct User {
        name: String,
        count: u64,
        active: bool,
    }
// 2、创建结构体实例
    let xiaoming = User {
        name: String::from("xiaoming"),
        count: 120,
        active: true
    };
    println!("xiaoming active = {}",xiaoming.active);
// 3、修改结构体实例 添加mut
    let mut xiaohuang = User {
        name: String::from("xiaoming"),
        count: 120,
        active: true
    };
    xiaohuang.active = false;
    println!("{}",xiaohuang.active);
// 4、参数名字和字段名字同名的简写方法
    let name = String::from("Hello");
    let mut xiaohuangfei = User {
        // name: name,
        name,
        count: 120,
        active: true
    };
    println!("{}",xiaohuangfei.name);
// 5、从其他结构体创建实例
    let name1 = String::from("Hello");

    let mut xiaohuangfei1 = User {
        // name: name,
        name: name1,
        count: 120,
        active: true
    };
    let user2 = User  {
         active: false,
        ..xiaohuangfei1
    };
    println!("{}", user2.name);
// 6、元组结构体
    // 1、字段没有名字
    // 2、圆括号
    struct Point(i32, i32);
    let a = Point(1,1);
    println!("{}",a.0);
// 7、没有任何字段的结构体
    struct A{};

// 8、打印结构体
    // 在定义的结构体上加上#[derive(Debug)]
    #[derive(Debug)]
    struct Card {
        num: i32,
        active: bool
    }
    let xiao = Card {
        num: 123,
        active: true
    };
    println!("xiao = {:?}",xiao); // 打印时花括号里面是:?    xiao = Card { num: 123, active: true }
    println!("xiao = {:#?}",xiao); // 自动换行,如下:
                                    // xiao = Card {
                                    //     num: 123,
                                    //     active: true,
                                    // }
// 方法
#[derive(Debug)]
struct Dog {
    name: String,
}
impl Dog {
    fn get_name(&self) -> &str {
        &(self.name[..])
    }
    fn show () {
        println!("h h h");
    }
}

// 实例
let dog = Dog {
    name: String::from("wangcia"),
};

Dog::show();

println!("{:#?}",dog);
println!("{}", dog.get_name());

// 枚举类型与匹配
// rust语言提倡的做法
    enum IpArrs {
        V4(String),
        V6(String),
    }

    let i1 = IpArrs::V4(String::from("127.0.0.1"));
    let i2 = IpArrs::V6(String::from("127.0.0.1"));
    // 可以定义不同的类型
        enum  Ipaddr {
            V4(u8,u8,u8,u8),
        }
        let v4 = Ipaddr::V4(127,0, 0, 1);
// 经典用法
enum Message {
    Quit,
    Move{x: i32, y: i32},
    Write(String),
    Change(i32, i32, i32),
}
// 枚举类型的方法以及match(类似switch)
impl Message {
    fn prin(&self) {
        match *self {
            Message::Quit => println!("n"),
            Message::Move{x, y} => println!("{},{}",x, y),
            Message::Change(a,b, c) => println!("{},{},{}",a,b,c),
            _=>println!("default")
        }
    }
}
// 实例:
let quit = Message::Quit;
quit.prin();
let move1 = Message::Move { x: 32, y: 32 };
move1.prin();
let chanage = Message::Change(15, 20, 21);
chanage.prin();
let write = Message::Write(String::from("hello pip"));
write.prin();
// Option是标准库定义的一个枚举,形式:
    enum Option<T> {
        Some(T),
        None
    }
    // 使用方式
    let opti = Some(5); // 会类型推导
    let yu = Some(5);
    let mut temp = 0;
    match yu {
        Some(i) => { temp = i; }
        None => { println!("do nothing"); }
    }
    let sum = 5 + temp;

    // fn add (ty: Option<i32>) -> Option<i32> {
    //     match ty {
    //         Some(ty) => Some(ty + 1),
    //         None => println!("sss"),
    //     }
    // }
    // add(25);
// vector
let mut v: Vec<i32> = Vec::new(); // 创建空的vector
v.push(1);
println!("vector={:?}",v);

let vs = vec![1,2,3]; // 默认值得Vec
println!("{:?}", vs);

{
    let ve = vec![1,8];
}

// 读取Vector-索引获取
let one: &i32 = &vs[0];
println!("{}",*one);

let two: &i32 = &vs[0];
println!("{}",*two);

// vector match获取(rust 推荐的方法)
let vs1 = vec![1,2,3]; // 默认值得Vec
match vs1.get(10) {
    Some(value) => println!("{}", value),
    _=>println!("nono"),
}
// 更新Vector
let mut v4: Vec<i32> = Vec::new();
v4.push(1);

// vector遍历
// 1、只读遍历
for i in &v4 {
    println!("i = {}",i);
}
// 2、可变的遍历 
for i in &mut v4 {
    *i+=1;
    println!("{}",i);
}
// 使用枚举类型
enum Content {
    Text(String),
    Float(f32),
    Int(i32),
}
let s = vec![
    Content::Text(String::from("String")),
    Content::Float(0.01),
    Content::Int(88),
];
// string
let strr = String::new();// 空串
let mut strrrr = String::from("heool");
let s1 = "init string".to_string();

strrrr.push_str("pop"); // 更新push_str,
strrrr = strrrr + "sdsdsd"; // 拼接字符串
strrrr.push('s'); // 同时push只能添加一个字符
println!("{}",&strrrr);

// string之format方法
let ok = String::from("a");
let sh = String::from("b");
let saa = format!("{}-{}",ok,sh); // a-b
println!("{}", saa);
// strig不能被索引
let ins = String::from("ssss是");
println!("{}",ins.len());
// string之遍历chars
for c in ins.chars() {
    println!("{}",c); // s s s s 是
}
// string之遍历bytes
for b in ins.bytes() {
    println!("{}",b);
}
// HashMap
// 头部使用导入库 use std::collections::HashMap;
let mut map :HashMap<String, i32> = HashMap::new();
map.insert(String::from("blue"), 325); // 插入值 

// 合并HashMap 推荐使用
let keys = vec![String::from("yrl"),String::from("uoi")]; // 创建容器
let value = vec![10,20];
let map1:HashMap<_,_> = keys.iter().zip(value.iter()).collect(); // iter是迭代器

// 读取HashMap
let k = String::from("yrl");
let rr = map1.get(&k);
println!("rr = {:?}",&rr); // rr = some(10)
if let Some(v) = map1.get(&k){ // 判空
    println!("v = {:?}",v); // v = 10
}

match rr {
    Some(value) => println!("v = {}", value),
    None => println!("none")
}

// 当键不存在才插入
map.entry(String::from("ssd")).or_insert(3); // 当键值ssd不存在时插入3

// 根据旧值来更新一个值
let iu =map.entry(String::from("ssd")).or_insert(3);
*iu += 1;
// 打印验证
let kse = String::from("ssd");
if let Some(v) = map.get(&kse){ // 判空
    println!("iu = {:?}",v); // v = 4
}

// 错误
// 1、可恢复错误通常代表向用户报告错误和重试操作是合理的情况,例如未找到文件。rust中使用Result<T, E>来实现
// 2、不可恢复是bug的同义词,如尝试访问超过数组结尾的位置》rust通过panic来实现
// panic!("error muriming"); //thread 'main' panicked at 'error muriming', src\main.rs:422:5
//Reault<T,E>
// enum Result<T,E> {
//     Ok(T),
//     Err(E)
// }
// let f = File::open("hello.txt");
// let r = match f {
//     Ok(file) => file,
//     Err(error) => panic!("error open file"), // thread 'main' panicked at 'error open file', src\main.rs:432:23
// };
// 简写1
// let f1 = File::open("hello.txt").unwrap();
// 简写2
// let f2 = File::open("hello.txt").expect("file no error");

// 什么时候使用panic?什么时候使用Result

}