由于一個學期沒有碰Rust,相關(guān)知識殆已忘盡。最近各課逐漸停授,余出時間來從基礎重溫這些知識,也算是對沒有寫的基礎知識的補充。另外這次復習主要參照了Youtube上的Crush Course視頻,兩個小時的視頻一氣看下來還是很累的啊。原視頻鏈接
下載Rust,并在VSCode環(huán)境下使用
首先打開Rust官網(wǎng),點擊Get Started,下載對應的64位版本。運行下載程序并啟用默認設置就可以。我的電腦里已經(jīng)有舊版本,故只進行了更新操作。然后找到下載的bin文件夾路徑添加環(huán)境變量即可,這個路徑一般在users/YourName/.cargo/bin 中
然后在VSCode的插件里搜索Rust,安裝列表第一個插件即可。下面運行第一個小程序。
- 打開任意文件夾,創(chuàng)建一個文件
Hello.rs ,在里面輸入如下代碼:
fn main(){
println!("Hello, World!");
}
- 在終端中輸入
rustc "Hello.rs" ,正常編譯后會在相同路徑下出現(xiàn)對應的Hello.exe ,運行時即在終端輸出
> Hello, World!
刪除這些文件,在一個空文件夾里新建一個空工程。在終端輸入如下指令:cargo init
Rust會為你自動生成一個完備的工程文件,包含一個Hello World程序。編譯正常運行,到此基本配置已經(jīng)結(jié)束。接下來就是Rust的一些基礎使用方法。不過要指出的是這些內(nèi)容并沒有涉及到Rust的核心,也就是說幾乎只是一個套皮的C、Python、Java或者其他語言的另一種寫法。關(guān)于Rust的獨到之處,還要進一步復習。在此只是記錄備忘。
基本輸出
把內(nèi)容和參數(shù)打印到屏幕上可能是學習每門語言最先接觸的東西了。Rust輸出參數(shù)的時候會用到{} ,是在哪里見過呢……
//原始形態(tài)
println!("Hello, world!");
//參數(shù)用{}標記
println!("Number: {}",1+2);
//{}中可加入指示位置的數(shù)字
println!("{1},{0},{2},{0}",
"Alice","Bob","Eve");
//{}中可加入?yún)?shù)名,不過要在參數(shù)列表處加以說明
println!("{name} stands by {num}",
name = "Bob",num = 1);
//格式化輸出
println!("Binary:{:b} Hex:{:x} Oct:{:o}",10,10,10);
//{:?}可以輸出元組,準確的說可以打印任何類型的具體信息。好像可以用來debug?
println!("{:?}",(12,true,"Hello"));
//參數(shù)列表可以進行簡單的數(shù)學運算,這一點與C/C++等多數(shù)語言相同,不再贅述
定義變量
Rust中定義變量一般不需指明類型,而且默認是不可以改變其中的值的。要想改變需要額外添加mut字段。
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 + 數(shù)字(8/16/32/64/128) 表示 如u8,i64
- 浮點型有f32和f64兩個類型
- 布爾型 bool
- 字符類型 Char
- Tuples和Arrays
//普通整型默認為 "i32"類型
let x = 1;
//普通浮點數(shù)默認為"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);
字符串類型
相似,不贅述
let mut hello = String::from("Hello!"); //聲明一個可變字符串變量
println!("{}",hello);
//有判空、獲得長度、獲得占用空間、接續(xù)字符/字符串等類方法
println!("Length: {}",hello.len());
hello.push('!');
println!("{}",hello);
hello.push_str("???");
println!("{}",hello);
println!("cap:{}",hello.capacity());
println!("isEmpty:{}",hello.is_empty());
//可以匹配內(nèi)部內(nèi)容,如contain返回是否包含字段,replace返回替換指定內(nèi)容的字符串(不改變原本內(nèi)容)
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);
tuple元組
元組是不同類型數(shù)據(jù)的集合,最多擁有十二個數(shù)據(jù)。
let person:(&str,&str,i8) = ("Brad","Mass",20);
println!("{} is from {} and is {}",person.0,person.1,person.2);
靜態(tài)數(shù)組array
支持索引、切片。
//顯式指定類型和長度
let mut numbers :[i32;5] = [1,2,3,4,5];
//let numbers :[i32;5] = [1,2,3,4]; //會報錯-長度必須匹配
println!("{:?}",numbers);
//用索引得到單獨的值
println!("{}",numbers[1]);
//對可變的數(shù)組可以對其中的值單獨重新賦值
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);
動態(tài)數(shù)組vectors
和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);
}
//用可變迭代器可以對內(nèi)容進行修改
for x in numbers.iter_mut(){
*x *=2;
}
println!("Numbers Vec:{:?}",numbers);
邏輯結(jié)構(gòu)
條件語句
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);
循環(huán)語句
let mut count = 0;
//最基本的loop循環(huán),需要內(nèi)部指明跳出條件
loop{
count += 1;
println!("Number: {}",count);
if count == 5{
break;}
}
//while循環(huán),用法類似其他
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循環(huán),遍歷容器中的內(nèi)容
for x in 0..20{
if x % 5 == 0 {println!("Go!{}",x);}
}
函數(shù)調(diào)用
參數(shù)的聲明以及返回值的書寫比較值得注意,閉包的寫法也要注意
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 //返回值后面沒有分號
}
引用指針
這里只是簡單的介紹,還有很多內(nèi)容沒有寫入
let arr1 = [1,2,3];
let arr2 = arr1;
println!("{:?}",arr1);
println!("{:?}",arr2);
//Array為原生類型,因此在這里無事發(fā)生
//非原生類型重新賦值時會導致賦值方不再保留原來的內(nèi)容,出現(xiàn)所有權(quán)的移交
//這種情況下需要使用引用指針
let vec1 = vec![1,2,3];
let vec2 = &vec1; //使用了引用,vec1認為無事發(fā)生
//let vec2 = vec1; //這個語句會導致vec1不再擁有原來的數(shù)據(jù)
println!("Val:{:?}",(&vec1,vec2));
結(jié)構(gòu)體
比較特殊,從成員變量的聲明到成員函數(shù)的加入。
//最基本的結(jié)構(gòu)體,注意成員變量間用','分隔
struct Color {
red: u8,
green: u8,
blue: u8,
}
//元組的形式聲明的結(jié)構(gòu)體
struct Color2(u8,u8,u8);
//一個部署了成員方法的結(jié)構(gòu)體,方法在后面用impl引出
struct Person{
first_name: String,
last_name: String,
}
impl Person{
//構(gòu)造函數(shù)
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);
//初始化元組結(jié)構(gòu)體
let mut d = Color2(0,255,0);
//使用和修改時指明位置
println!("Color: {} {} {}",d.0,d.1,d.2);
//使用構(gòu)造函數(shù)和其他成員函數(shù)
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());
}
枚舉類
枚舉是只有具體的幾個值的數(shù)據(jù)類型。具體值由編寫者確定。
enum Movement{
Up, Down, Left, Right
}
可以作為參數(shù),也可以用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的基本寫法。
|