Rust的入门篇(上)
最近跟着菜鸟一起入门了比较火的Rust语言,下面整理一下学习的笔记吧。
1. Helloworld程序
fn main(){println!("hello rust")
}
2. 格式化字符串
fn main(){let a = 12;// 格式化字符串println!("a={}", a);println!("a={}, a={}", a, a);println!("a={0}, again a={0}", a);println!("{{}}")}
3. 基础运算
fn main(){// 不可变的变量,强类型语言,但是会自动推测变量的类型let a = 123;let a = 1234;// 上面是合法的,可以重复声明// 可改变的变量let mut a = 123;a = 456;println!("{}", a);// const b = 123;// let b = 456;// 手动指定变量的类型,如果不指定,默认是u32let c : u64 = 345;// 变量的重影 shadowing 大直白是自己给自己赋值let x = 5;let x = x + 1;let x = x * 2;// 12println!("The value of x is {}", x);}
4. 变量的类型
fn main(){// 默认推测的是f64let a = 2.0;let y:f32 = 3.0;let sum = 5 + 10;let difference = 95.5 - 4.3;let product = 4 * 30;let quotient = 56.7 / 32.2;let remainder = 423 % 5;// 复合类型 元组let tup:(i32, f64, u8) = (500, 6.4, 1);let (x, y, z) = tup;// y=6.4println!("y={}", y);let a = [1, 2, 3, 4, 5];let b = ["January", "February", "March"];let c:[i32; 5] = [1, 2, 3, 4, 5];// 等同于 let d = [3, 3, 3, 3, 3];let d = [3;5];let first = a[0];let second = a[1];println!("first={}, second={}", first, second);// a[0] = 123; // 错误,数组a不可变let mut a = [1, 2, 3];a[0] = 4;// println!("{}", a);}
5. 函数举例
fn main(){println!("Hello, world!");let x = 5;let y = {let x = 3;x + 1};println!("x={}", x);println!("y={}", y);fn five()->i32{5}println!("five={}", five());}fn another_function(){println!("Hello, runoob!");
}fn add(a:i32, b:i32)->i32{return a+b;
}
6. 条件语句
fn main(){let number = 3;// 条件语句if number < 5{println!("true");} else {println!("false");}let a = 3;// 三目运算符let number = if a > 0 {1} else {-1};println!("number={}", number);
}
7. 循环
fn main(){let mut number = 1;// while语句while number!=4{println!("{}", number);number += 1;}println!("EXIT");// while循环let mut i = 0;while i < 10 {i += 1;}println!("i={}", i);// for 语句let a = [10, 20, 30, 40, 50];for i in a.iter(){println!("a={} ", i);}// 下标访问let a = [10, 20, 30, 40, 50];for i in 0..5{println!("a[{}] = {}", i, a[i]);}// loop无线循环let s = ['R', 'U', 'N', 'O', 'O', 'B'];let mut i = 0;loop {let ch = s[i];if ch == 'O'{break;}println!("\'{}\'", ch);i += 1;}let s = ['R', 'U', 'N', 'O', 'O', 'B'];let mut i = 0;let location = loop{let ch = s[i];if ch == 'O'{break i;}i += 1;};println!(" \'O\' index {}", location);}
8. 所有权一
所有权是Rust里面一个比较新的概念。一个变量赋值到另一个变量上面的时候,所有权就会发生转移,如果这时候再去访问原来的变量就会出错了。
fn main(){// 所有权let a = "hello";let b = a;println!("{} world", b);let s1 = String::from("world");let s2 = s1;// 错误 s1 已经不存在了// println!("{}, world", s1); println!("{}, world", s2);let s1 = String::from("hello");// 使用克隆解决上面的问题let s2 = s1.clone();println!("s1={}, s2={}", s1, s2);}
9. 所有权二
// 函数所有权机制fn main(){let s = String::from("hello");// 所有权转移到函数中take_ownership(s);// 报错了,s已经不存在了// println!("{}", s);let x = 5;makes_copy(x);println!("{}", x);}fn take_ownership(some_string: String){println!("{}", some_string);
}fn makes_copy(some_integer:i32){println!("{}", some_integer);
}
10. 所有权三 函数所有权转移
// 函数所有权机制fn main(){let s1 = gives_ownership();let s2 = String::from("hello");let s3 = takes_and_gives_back(s2);println!("s3={}", s3);}// 返回所有权
fn gives_ownership()->String{let some_string = String::from("hello");return some_string;
}// 获取和返回所有权
fn takes_and_gives_back(a_string:String)->String{return a_string; // 被当做返回值移出函数
}
11. 所有权四 引用
// 引用与租借
fn main(){let s1 = String::from("hello");// 引用并不会交出所有权let s2 = &s1;println!("s1 is {}, s2 is {}", s1, s2);// 引用传参let s1 = String::from("hello");let len = calculate_length(&s1);println!("The length of '{}' is {}.", s1, len);}// 引用传参
fn calculate_length(s:&String)->usize{s.len()
}
12. 引用四 可变引用
fn main(){// 引用只是把所有权租借,容易产生问题的代码let s1 = String::from("hello");// s2引用了s1let mut s2 = &s1;// s1把拥有权给了s3,s1不再可用let s3 = s1;// 下面错误,s2租借的s1已经不可用// println!("{}", s2);// s2重新向s3 borrow所有权s2 = &s3;println!("s2={}", s2);let mut s4 = String::from("hello");s4.push_str(" world");println!("{}", s4);// s5引用s4let s5 = &s4;// 错误,租借后不允许修改// s5.push_str(" rust");// 如果需要修改,s6引用s4并允许修改let s6 = &mut s4;s6.push_str(" oob");println!("{}", s6);// 不可以被多次可变引用let mut s7 = String::from("hello");// let r1 = &mut s7;// let r2 = &mut s7;// println!("r1={}, r2={}", r1, r2);// // 垂悬引用, 不允许出现// let ref_nothing = dangle();}// 垂悬引用, 不允许出现
// fn dangle()->&String{
// let s = String::from("hello");
// &s
// }
13. slice 字符串切片操作
// 切片操作
fn main(){let s = String::from("broadcast");// 字符串切片let part1 = &s[0..5];let part2 = &s[5..9];println!("{}={}+{}", s, part1, part2);//被切片引用的字符串禁止更改其值// let mut s = String::from("runoob");// let slice = &s[0..3];// slice.push_str("yes!");// println!("slice={}", slice);// String 类型是 Rust 标准公共库提供的一种数据类型,// 它的功能更完善——它支持字符串的追加、清空等实用的操作。// String 和 str 除了同样拥有一个字符开始位置属性和一个字符串长度// 属性以外还有一个容量(capacity)属性。let slice = &s[0..3];// 快速将String转成&strlet s1 = String::from("hello");let s2 = &s1[..];// 其他数据类型的切片操作let arr = [1, 3, 5, 7, 9];let part = &arr[0..3];for i in part.iter(){println!("i={}", i);}}
14. 结构体一
// 结构体use std::string;fn main(){// 初始化结构体let runoob = Site{domain: String::from("www.runoob.com"),name: String::from("runnob"),nation: String::from("china"),found: 2013};let domain = String::from("www.runoob.com");let name = String::from("runoob");let runnob2 = Site{domain,name,nation:String::from("china"),found: 2013};// 使用旧结构体的部分属性来新建新的结构体let site = Site{domain: String::from("www.runoob.com"),name: String::from("runoob"),..runoob};// 元组结构体初始化let black = Color(0, 0, 0);let origin: Point = Point(0.0, 0.0);println!("black = ({}, {}, {})", black.0, black.1, black.2);println!("origin = ({}, {})", origin.0, origin.1);// 打印结构体let rect1 = Rectangle{width:30,height:50};// println!("rect1 is {:#?}", rect1);}// 结构体
struct Site{domain:String,name:String,nation:String,found:u32
}// 元组结构体
struct Color(u8, u8, u8);
struct Point(f64, f64);// 输出完整的结构体
struct Rectangle{width: u32,height: u32,
}
15. 结构体二 结构体方法
结构体方法的第一个参数必须是 &self,不需声明类型,因为 self 不是一种风格而是关键字。
fn main(){let rect1 = Rectangle{width:30, height:50};println!("rect1's area is {}", rect1.area());
}struct Rectangle{width: u32,height: u32,
}impl Rectangle {fn area(&self)->u32{self.width*self.height}
}
16. 结构体三
fn main(){let rect1 = Rectangle{width:30, height:50};let rect2=Rectangle{width:40, height:20};println!("{}", rect1.wider(&rect2));}struct Rectangle{width: u32,height: u32,
}// 结构体方法
impl Rectangle {fn area(&self)->u32{self.width*self.height}fn wider(&self, rect:&Rectangle)->bool{self.width > rect.width}
}
17. 枚举类型一
fn main(){enum Book {Popery(u32),Electronic(String),}let book = Book::Popery(1001);let ebook = Book::Electronic(String::from("url://..."));}
18. 枚举类型二
fn main(){// 枚举属性命名enum Book {Papery {index: u32},Electronic{url: String},}let book = Book::Papery { index: 1001 };}
19. 枚举类型三
fn main(){// 枚举属性命名enum Book {Papery {index: u32},Electronic{url: String},}let book = Book::Papery { index: 1001 };let ebook = Book::Electronic { url: String::from("url...") };// 打印book有的属性match book{Book::Papery { index } =>{println!("Papery book {}", index);},Book::Electronic { url }=>{println!("E-book {}", url);}}// 打印ebook有的属性match ebook{Book::Papery { index } =>{println!("Papery book {}", index);},Book::Electronic { url }=>{println!("E-book {}", url);}}}
20. 枚举类型四
// option 枚举类
fn main(){let opt = Option::Some("hello");match opt{Option::Some(something)=>{println!("{}", something);},Option::None=>{println!("opt is nothing");}}// hellolet opt1:Option<&str> = Option::None;match opt1{Option::Some(something)=>{println!("{}", something);}Option::None=>{println!("opt1 is nothing");}}// opt is nothing// 由于 Option 是 Rust 编译器默认引入的,在使用时可以省略 Option:: 直接写 None 或者 Some()。let t = Some(64);match t{Some(64)=>println!("yes"),_=>println!("No"),}// yes}
21. 枚举类型五
// option 枚举类
fn main(){// if let 用法let i = 0;if let 0 = i {println!("zero");}enum Book {Papery(u32),Electronic(String)}let book = Book::Electronic(String::from("url"));if let Book::Papery(index) = book{println!("Papery {}", index);}else{println!("Not papery book");}// Not papery book}