因为一个学期没有碰Rust,相关知识殆已忘尽。最近各课逐渐停授,余出时间来从基础重温这些知识,也算是对没有写的基础知识的补充。另外此次复习主要参照了Youtube上的Crush Course视频,两个小时的视频一气看下来仍是很累的啊。原视频连接小程序
首先打开Rust官网,点击Get Started,下载对应的64位版本。运行下载程序并启用默认设置就能够。个人电脑里已经有旧版本,故只进行了更新操做。而后找到下载的bin文件夹路径添加环境变量便可,这个路径通常在users/YourName/.cargo/bin
中数组
而后在VSCode的插件里搜索Rust,安装列表第一个插件便可。下面运行第一个小程序。闭包
Hello.rs
,在里面输入以下代码:fn main(){ println!("Hello, World!"); }
rustc "Hello.rs"
,正常编译后会在相同路径下出现对应的Hello.exe
,运行时即在终端输出> Hello, World!
删除这些文件,在一个空文件夹里新建一个空工程。在终端输入以下指令:cargo init
函数
Rust会为你自动生成一个完备的工程文件,包含一个Hello World程序。编译正常运行,到此基本配置已经结束。接下来就是Rust的一些基础使用方法。不过要指出的是这些内容并无涉及到Rust的核心,也就是说几乎只是一个套皮的C、Python、Java或者其余语言的另外一种写法。关于Rust的独到之处,还要进一步复习。在此只是记录备忘。oop
把内容和参数打印到屏幕上多是学习每门语言最早接触的东西了。Rust输出参数的时候会用到{}
,是在哪里见过呢……学习
//原始形态 println!("Hello, world!"); //参数用{}标记 println!("Number: {}",1+2); //{}中可加入指示位置的数字 println!("{1},{0},{2},{0}", "Alice","Bob","Eve"); //{}中可加入参数名,不过要在参数列表处加以说明 println!("{name} stands by {num}", name = "Bob",num = 1); //格式化输出 println!("Binary:{:b} Hex:{:x} Oct:{:o}",10,10,10); //{:?}能够输出元组,准确的说能够打印任何类型的具体信息。好像能够用来debug? println!("{:?}",(12,true,"Hello")); //参数列表能够进行简单的数学运算,这一点与C/C++等多数语言相同,再也不赘述
Rust中定义变量通常不需指明类型,并且默认是不能够改变其中的值的。要想改变须要额外添加mut字段。spa
let name = "Brad"; let age_1 = 20; //age_1 = 21; //这里会报错,由于默认age_1是不能够改变的 let mut age = 20; println!("I am {}",age); //输出20 age = 21; println!("I am now {}", age); //输出21 println!("My name is {}", name); //也能够定义常量 const ID:i32 = 001; //在变量名后面添加 :类型名 来指定类型 println!("My ID: {}",ID); //能够一次定义多个变量 let (my_name, my_age) = ("Bob", 20); println!("{} is {}", my_name, my_age);
Rust中的一些基本类型见下:插件
- 整形用i/u + 数字(8/16/32/64/128) 表示 如u8,i64
//普通整型默认为 "i32"类型 let x = 1; //普通浮点数默认为"f64"类型 let y = 1.2; //显式定义类型 let y:i64 = 123456789; //显示Max size println!("Max i32: {}", std::i32::MAX); println!("Max i64: {}", std::i64::MAX); //定义布尔值 let is_Act = true; println!("{:?}",(x,y,is_Act)); //也能够从表达式得到bool值,不赘述* //甚至能够用unicode保存emoji,格式为"\u{codeX}" let face = '\u{1f600}'; println!("{}",face);
类似,不赘述debug
let mut hello = String::from("Hello!"); //声明一个可变字符串变量 println!("{}",hello); //有判空、得到长度、得到占用空间、接续字符/字符串等类方法 println!("Length: {}",hello.len()); hello.push('!'); println!("{}",hello); hello.push_str("???"); println!("{}",hello); println!("cap:{}",hello.capacity()); println!("isEmpty:{}",hello.is_empty()); //能够匹配内部内容,如contain返回是否包含字段,replace返回替换指定内容的字符串(不改变本来内容) println!("Contains \"Hello\"?: {}",hello.contains("Hello")); println!("Contains \"World\"?: {}",hello.contains("World")); println!("Replace: {}",hello.replace("llo", "LLO")); hello = String::from("Hello world!"); for word in hello.split_whitespace(){ println!("{}",word); } //能够指定字符串所占的空间 let mut s = String::with_capacity(10); s.push('a'); s.push('b'); //断言语句,不成立时投出panic //assert_eq!(3,s.len()); //cause panic! assert_eq!(2,s.len()); println!("{}",s);
元组是不一样类型数据的集合,最多拥有十二个数据。指针
let person:(&str,&str,i8) = ("Brad","Mass",20); println!("{} is from {} and is {}",person.0,person.1,person.2);
支持索引、切片。
//显式指定类型和长度 let mut numbers :[i32;5] = [1,2,3,4,5]; //let numbers :[i32;5] = [1,2,3,4]; //会报错-长度必须匹配 println!("{:?}",numbers); //用索引获得单独的值 println!("{}",numbers[1]); //对可变的数组能够对其中的值单独从新赋值 numbers[2] = 12; println!("{:?}",numbers); //求长度 println!("Array Len: {}", numbers.len()); //这里使用std::mem库得到占有空间大小 println!("Array occupies {} bytes",std::mem::size_of_val(&numbers)); //切片语法 let slc:&[i32] = &numbers[0..2]; println!("Slice:{:?}",slc);
和array相似,能够push和pop,用迭代器进行遍历
//只要明确类型 let mut numbers: Vec<i32> = vec![1,2,3,4]; //添加 numbers.push(5); println!("{:?}",numbers); //弹出首元素 numbers.pop(); println!("{:?}",numbers); //用迭代器进行遍历 for x in numbers.iter(){ println!("Numbers: {}",x); } //用可变迭代器能够对内容进行修改 for x in numbers.iter_mut(){ *x *=2; } println!("Numbers Vec:{:?}",numbers);
let age = 15; let gender:char = 'M'; //If-else if age>=18 { println!("Adult!"); } else { println!("Not"); } if age<=18 && gender=='M'{ println!("Boy"); } //用if-else进行快速赋值,相似于?:表达式 let is_adult = if age >= 18 {true} else {false}; println!("An adult: {}", is_adult);
let mut count = 0; //最基本的loop循环,须要内部指明跳出条件 loop{ count += 1; println!("Number: {}",count); if count == 5{ break;} } //while循环,用法相似其余 while count <= 100{ if count % 15 == 0{ println!("Fuzzbuzz"); } else if count % 25 == 0{ println!("by 25"); } else if count % 5 == 0 { println!("{}",count); } count += 1; } //for循环,遍历容器中的内容 for x in 0..20{ if x % 5 == 0 {println!("Go!{}",x);} }
参数的声明以及返回值的书写比较值得注意,闭包的写法也要注意
pub fn run(){ greeting("Jane", "Hello"); println!("2+3={}",add(2,3)); //闭包可使用外部的变量 let n3:i32 = 3; let add_nums = |n1:i32, n2:i32| n1 + n2 + n3; println!("Sum:{}",add_nums(1,2)); } fn greeting(greet: &str, name: &str){ println!("{},{}!",greet,name); } fn add(n1:i32, n2:i32) -> i32 //类型在此声明 { n1 + n2 //返回值后面没有分号 }
这里只是简单的介绍,还有不少内容没有写入
let arr1 = [1,2,3]; let arr2 = arr1; println!("{:?}",arr1); println!("{:?}",arr2); //Array为原生类型,所以在这里无事发生 //非原生类型从新赋值时会致使赋值方再也不保留原来的内容,出现全部权的移交 //这种状况下须要使用引用指针 let vec1 = vec![1,2,3]; let vec2 = &vec1; //使用了引用,vec1认为无事发生 //let vec2 = vec1; //这个语句会致使vec1再也不拥有原来的数据 println!("Val:{:?}",(&vec1,vec2));
比较特殊,从成员变量的声明到成员函数的加入。
//最基本的结构体,注意成员变量间用','分隔 struct Color { red: u8, green: u8, blue: u8, } //元组的形式声明的结构体 struct Color2(u8,u8,u8); //一个部署了成员方法的结构体,方法在后面用impl引出 struct Person{ first_name: String, last_name: String, } impl Person{ //构造函数 fn new(first: &str, last: &str) -> Person{ Person{ first_name: first.to_string(), last_name: last.to_string(), } } fn full_name(&self) -> String{ format!("{} {}", self.first_name,self.last_name) } fn set_last_name(&mut self, last: &str){ self.last_name = last.to_string(); } fn to_tuple(self) -> (String,String){ (self.first_name,self.last_name) } } pub fn run(){ //最基本的初始化方法 let mut c = Color { red: 255, green: 0, blue: 0, }; //使用和修改时指明名称便可 println!("Color: {} {} {}",c.red,c.green,c.blue); c.red = 200; println!("Color: {} {} {}",c.red,c.green,c.blue); //初始化元组结构体 let mut d = Color2(0,255,0); //使用和修改时指明位置 println!("Color: {} {} {}",d.0,d.1,d.2); //使用构造函数和其余成员函数 let mut p = Person::new("John", "Doe"); println!("Person {} {}",p.first_name,p.last_name); println!("Person {}",p.full_name()); p.set_last_name("Williams"); println!("Person {}",p.full_name()); println!("{:?}",p.to_tuple()); }
枚举是只有具体的几个值的数据类型。具体值由编写者肯定。
enum Movement{ Up, Down, Left, Right }
能够做为参数,也能够用match进行选择
fn move_avatar(m: Movement){ match m { Movement::Up => println!("Avatar moving up"), Movement::Down => println!("Avatar moving down"), Movement::Left => println!("Avatar moving left"), Movement::Right => println!("Avatar moving right"), }//match相似于switch,注意用=>指向具体操做,之间用逗号分隔。 } pub fn run(){ let avatar1 = Movement::Up; let avatar2 = Movement::Down; let avatar3 = Movement::Left; let avatar4 = Movement::Right; move_avatar(avatar2); move_avatar(avatar3); move_avatar(avatar1); move_avatar(avatar4); }
以上介绍了Rust的基本写法。