下面是 rust 语法基本使用笔记,保存到文件直接可以运行
fn main() { for_const(); for_var(); for_condition(); for_loop(); for_tuple(); for_array(); for_ownership(); for_borrow(); for_slice(); for_struct(); for_enum(); for_mod(); for_collections(); for_error(); for_closure(); for_pointer(); for_thread(); for_stdin(); for_file(); } // 常量 fn for_const() { mark("常量"); // 基本数据类型(整型,浮点型,布尔类型,字符类型) // 1.只能赋值,名称要大写 // 2.数据类型不可以忽略 // 3.不能出现同名 const SERVER: &'static str = "https://zee.kim"; const PORT: u16 = 8080; println!("常量: {}:{}", SERVER, PORT); } // 设置类型和变量 fn for_var() { mark("设置类型和变量"); /* 大小 有符号 无符号 8 bit i8 u8 16 bit i16 u16 32 bit i32 u32 64 bit i64 u64 128 bit i128 u128 Arch isize usize(x86 机器上为 32 位,在 x64 机器上为 64 位) */ let _int: usize = 1024; println!("整数: {}", _int); println!("最大整数: {}", std::u128::MAX); println!("最小整数: {}", std::i128::MIN); let _float: f64 = 89_898.141_526; //数字分隔符“_”,更容易看清 println!("浮点: {}", _float); let _bool: bool = true; println!("布尔值: {}", _bool); let _string: &str = "Huawei♥♥"; println!("字符串: {}", _string); let empty_string = String::new(); println!("长度是 {}", empty_string.len()); let content_string = String::from("简单教程"); println!("长度是 {}", content_string.len()); let name1 = " 幸福彼岸".to_string(); //原字符串对象 println!("去掉左右空格/回车/换行/制表符:{}", name1.trim()); let name2 = name1.replace("彼岸", "使者"); // 查找并替换 println!("{}", name2); let name3 = name2.contains("使者"); // 是否包含 let name4 = "#".repeat(4); //重复 println!("{}=>{}", name3, name4); let name5 = name2.as_str(); //将字符串对象转换为字符串字面量 println!("{}", name5); let name6 = name2.trim().chars(); //将字符串打散为字符数组 println!("{:?}", name6); let number = 2021; let number_as_string = number.to_string(); // 转换数字为字符串类型 println!("{}", number_as_string); println!("{}", number_as_string == "2021"); // 格式化宏 format! let n1 = 1024; let n2 = "KB".to_string(); let n3 = format!("{}{}", n1, n2); println!("{}", n3); // LET 变量 // 1.变量名中可以包含 字母、数字 和 下划线。 // 2.变量名必须以 字母 或 下划线 开头。 // 3.变量名是 区分大小 写的。 // 4.let 在第一次赋值之后不可重新赋值,如要变则要加mut let mut status = "yes"; println!("status: {}", status); status = "no"; println!("status: {}", status); } // 条件判断 // @不支持自增自减运算符 ++ 和 -- fn for_condition() { mark("条件判断"); let score = 80; if score == 100 { println!("满分!"); } else if score >= 80 { println!("合格"); } else { println!("不合格!"); } let sex = "1"; let sex_string = match sex { "0" => "女", "1" => "男", _ => "", }; println!("{}", sex_string); } // 循环语句 fn for_loop() { mark("循环语句"); for x in 1..3 { println!("x is {}", x); } let mut xx = 0; loop { xx += 1; if xx == 1 { continue; } if xx == 5 { break; } println!("loop {}", xx); } let mut xxx = 0; while xxx < 3 { xxx += 1; println!("while {}", xxx); } } // 元组 fn for_tuple() { mark("元组"); let tuple: (i32, f64, u8) = (-325, 4.9, 22); println!("{:?}", tuple); println!("integer is :{:?}", tuple.0); println!("float is :{:?}", tuple.1); println!("unsigned integer is :{:?}", tuple.2); } // 数组 // @数组中所有的元素的值初始化为 -1 // @数组可以理解为相同数据类型的值的集合 // @数组的定义其实就是为分配一段 连续的相同数据类型 的内存块。 // @数组是静态的。这意味着一旦定义和初始化,则永远不可更改它的长度。 // @数组下标从 0 开始。 // @可以更新或修改数组元素的值,但不能删除数组元素。如果要删除功能,你可以将它的值赋值为 0 或其它表示删除的值。 fn for_array() { mark("数组"); // 不可变 let arr: [i32; 4] = [10, 20, 30, 40]; println!("array is {:?}", arr); println!("array size is :{}", arr.len()); for val in arr.iter() { println!("数组 :{}", val); } for key in 0..4 { println!("数组 key:{},value:{}", key, arr[key]); } // 可变 let mut arr: [i32; 4] = [10, 20, 30, 40]; arr[1] = 0; println!("可变数组 {:?}", arr); } // 所有权 // @所有权只会发生在堆上分配的数据 // @基本类型的存储都在栈上,因此没有所有权的概念。 fn for_ownership() { mark("所有权"); let v = vec![1, 2, 3]; let v2 = v; //这里v嫁给了v2,就销毁了,后面不能再用了 println!("所有权 {:?}", v2); } // 借用 fn for_borrow() { mark("借用"); fn echo(x: &Vec) { // 1. 第一步,定义参数接受一个引用 println!("Inside print_vector function {:?}", x); } let v = vec![10, 20, 30]; echo(&v); // 传递变量的引用给函数 println!("{}", v[0]); // 可变的借用 // 1.变量本身是可变更的,也就是定义时必须添加 mut 关键字。 // 2.函数的参数也必须定义为可变更的,也就是必须添加 &mut 关键字。 // 3.传递 借用 Borrowing 或者说引用也必须声明时 可变更传递,也就是传递参数时必须添加 &mut 关键字。 fn mut_echo(x: &mut i32) { // 1. 第一步,定义参数接受一个引用 *x = 2; } let mut v2 = 1; mut_echo(&mut v2); println!("{}", v2); } // 切片(一般使用=>数组 array、向量 vector、字符串 string) // 1.一个 切片( slice ) 就是指向一段 内存 的指针 // 2.因此 切片 可用于访问内存块中 连续区间内的数据。 // 3.访问切片内容的时候,下标索引是从 0 开始的。 // 4.切片 的大小是运行时才可知的,并不是数组那种编译时就必须告知的。 fn for_slice() { mark("切片"); let n1 = "ABCDEDF".to_string(); println!("length: {}", n1.len()); let s1 = &n1[0..5]; println!("{}", s1); } // 结构体 // 1.结构体名 Name_of_structure 和元素/字段名 fieldN 遵循普通变量的命名语法。 // 2.结构体中中的每一个元素/字段都必须明确指定数据类型。可以是基本类型,也可以是另一个结构体。 fn for_struct() { mark("结构体"); struct Employee { name: String, company: String, age: u32, } let e = Employee { company: String::from("哇哈哈"), name: String::from("小李"), age: 50, }; println!( "Name is :{} company is {} age is {}", e.name, e.company, e.age ); let mut e2 = Employee { company: String::from("哇哈哈"), name: String::from("小李"), age: 50, }; e2.name = "金哲".to_string(); println!( "Name is :{} company is {} age is {}", e2.name, e2.company, e2.age ); // 实现方法 impl Employee { fn plus(&mut self) { self.age += 1; } fn new(company: String, name: String, age: u32) -> Employee { return Employee { company: company, name: name, age: age, }; } } let mut e3 = Employee::new("华为".to_string(), "李娜".to_string(), 30); e3.plus(); println!("New age is {}", e3.age); e3.plus(); println!("New age is {}", e3.age); } // 枚举 fn for_enum() { mark("枚举"); #[derive(Debug)] enum Color { Blue, Green, Red, } println!("{:?}/{:?}/{:?}", Color::Blue, Color::Green, Color::Red); } // 模块 fn for_mod() { mark("模块"); pub mod movies { pub fn play(name: String) { println!("Playing movie {}", name); } } movies::play("Herold and Kumar".to_string()); } // 容器 // Rust 语言的容器标准库提供了最常见的通用的数据结构的实现。包括 向量 (Vector)、哈希表( HashMap )、哈希集合( HashSet ) 等等。 fn for_collections() { mark("容器 Vec"); let mut v = Vec::new(); v.push(20); v.push(30); v.push(40); v.remove(1); //删除索引==1 if v.contains(&40) { println!("found 40"); } for i in &v { //借用,要不后面不能用了 println!("{}", i); } println!("size of vector is :{}", v.len()); println!("{:?}", v); mark("容器 HashMap"); // 哈希表 HashMap 就是 键值对 的集合 let mut m = std::collections::HashMap::new(); m.insert("name", "Zee"); //如果键已经存在,则更新为新的简直对,并则返回旧的值。 m.insert("site", "https://zee.kim"); m.insert("who", "balabala"); m.remove(&"who"); //移除 println!("{:?}", m); // 遍历 for (key, val) in m.iter() { println!("key: {} val: {}", key, val); } // 是否存在 if m.contains_key(&"name") { println!("found key"); } match m.get(&"name") { Some(value) => { println!("Value for key name is {}", value); } None => { println!("nothing found"); } } mark("容器 HashSet"); // 没有重复值的相同数据类型的值的集合 let mut s = std::collections::HashSet::new(); s.insert("Python"); s.insert("Rust"); s.insert("Ruby"); s.insert("PHP"); s.insert("Rust"); // 插入失败但不会引发异常 for language in s.iter() { println!("{}", language); } if s.contains(&"Rust") { println!("Contains found rust"); } match s.get(&"Rust") { Some(value) => { println!("Match found {}", value); } None => { println!("Not found"); } } s.remove(&"PHP"); println!("{:?}", s); } // 错误处理 fn for_error() { // let f = std::fs::File::open("main.jpg"); // main.jpg 文件不存在 // match f { // Ok(f)=> { // println!("file found {:?}",f); // }, // Err(e)=> { // println!("file not found \n{:?}",e); // 处理错误 // } // } // 自定义错误信息 // let f=std::fs::File::open("main.jpg").expect("error!"); // println!("file found {:?}",f); } // 闭包 fn for_closure() { mark("闭包"); let is_even = |x| x % 2 == 0; let no = 13; println!("{} is even ? {}", no, is_even(no)); } // 智能指针 fn for_pointer() { mark("智能指针"); let x = 5; // 值类型数据,存在栈上 let y = Box::new(x); // y 是一个智能指针,指向堆上存储的数据 5 println!("{}",5==x); println!("{}",5==*y); // 为了访问 y 存储的具体数据,需要解引用 } // 线程 fn for_thread(){ mark("线程"); let mut pool = vec![]; // 启动线程 for i in 0..10 as i32 { pool.push(std::thread::spawn(move || println!("this is {}", i))); } // 返回一个结果 for fish in pool { let _ = fish.join(); } } // 标准输入 fn for_stdin(){ mark("控制台输入"); let mut line = String::new(); println!("请输入你的名字:"); let b1 = std::io::stdin().read_line(&mut line).unwrap(); println!("你好 , {}", line); println!("读取的字节数为:{}", b1); } // 文件操作 fn for_file(){ mark("文件操作"); std::fs::write("data.txt", "2021-04-28").expect("could not write file"); println!("写文件data.txt"); let data = std::fs::read_to_string("data.txt").expect("could not read file"); println!("读文件:{:?}",data); std::fs::copy("data.txt", "bar.txt").expect("could not copy file"); std::fs::rename("bar.txt", "foo.txt").expect("could not rename file"); println!("bar.txt=>foo.txt"); std::fs::remove_file("foo.txt").expect("could not remove file"); println!("foo.txt is removed"); std::fs::create_dir_all("./abc").expect("could not create dir"); println!("dir is created"); std::fs::remove_dir_all("./abc").expect("could not remove dir"); println!("dir is removed"); std::fs::remove_file("data.txt").expect("could not remove file"); println!("data.txt is removed"); // 读取文件列表 fn get_files(target:String) { let path = std::path::Path::new(&target); let entrys = std::fs::read_dir(path).expect("Failed to read src directory"); for entry in entrys { if let Ok(entry) = entry { let dir = entry.path(); let name = dir.to_str().unwrap(); if name.contains(".DS_Store") { continue; } // println!("{:?}", dir); if dir.is_file() { println!("{}",name); }else{ get_files(name.to_string()) } } } } get_files("./src/".to_string()); } // 显示标题 fn mark(s: &str) { let left = "<".to_string().repeat(20); let right = ">".to_string().repeat(20); println!("{}", format!("{}{}{}", left, s.to_string(), right)); }