Rust快速入门
安装
linux & mac OS
1curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
创建项目
1cargo new hello
2cd hello
3
4cargo build
5cargo run
6cargo check
基本语法
变量
1// 1. 定义变量 let name :类型 = 值;
2let a = 1;
3// a = 2; // error
4let b: u32 = 2;
5let mut c = 3;
6c = 5;
7
8// 2. 隐藏 将上面的a=1隐藏,后续在使用a变量对应的值为10
9let a = 10;
10
11// 3. 常量 定义在main方法顶部
12const MAX_VALUE: u32 = 10000;
数据类型
- Rust是静态类型语言,即编译时必须知道所有变量的类型
- 编译器具有自动推导能力
基础数据类型
名字 | 零值 | 长度 | 描述 |
---|---|---|---|
bool | false | false 或者 true | |
char | 32bit | 值可以是 ‘a’ ‘中’ | |
i8,i16,i32,i64, u8,u16,u32,u64 | 0 | 数字类型 i符号,u无符号 | |
isize, usize | 自适应类型, 获取当前机器的usize最大值usize::max_value(); | ||
[Type; size] | 数组, let arr: [u32; 5] = [1, 2, 3, 4, 5]; , 当数组作为参数时, size也是数组的一部分, 用于限制参数:类型+size | ||
() | 元组, let tup: (i32, f32, char) = (1, 3.14, ‘你’); println!("{}", tup.0); |
函数
返回类型
1fn 方法的名字(参数: 参数类型, .....) -> 返回数据类型 { 2 return 返回值; 3}
返回结果
1fn login(t: i32, name: String) -> bool { 2 println!("type: {}, name: {}", t, name); 3 let result: bool = true; 4 // return result; 5 6 // 直接返回 不需要增加result和分号; 7 result 8}
表达式变量
1let value = { 2 let age = 18; 3 age + 1 4}
控制流
if
1
2let t = 1;
3if t == 1 {
4 println!("{}", t);
5} else if t > 1{
6 println!("{}", t);
7} else {
8 println!("{}", t);
9}
10
11let condition = true;
12let x = if condition {
13 5
14} else {
15 6
16 // "root" 出现error, 数据类型需要与if中的一致
17};
loop
1let mut conuter = 0;
2loop {
3 println!("{}", conuter);
4 if counter >= 10 {
5 break;
6 }
7 counter = counter + 1;
8 // counter += 1;
9}
10
11let sum = loop {
12 counter += 1;
13 if counter >= 10 {
14 break counter * 2;
15 }
16};
while
1let mut i = 0;
2while i != 10 {
3 i += 1;
4}
5println!("i: {}", i);
6
7let arr: [u32; 5] = [1, 2, 3, 4, 5];
8// for element in &arr {
9for element in arr.iter() {
10 println!("element: {}", element);
11}
所有权
Rust通过所有权机制来管理内存, 编译器在编译机会根据 所有权规则对内存的使用进行检查
- 规则1: ***
- 规则2: s
- 规则3: 2
堆栈
- 编译的时候数据类型大小是固定的, 就是分配在栈上
- 编译的时候数据类型大小不固定, 就分配到堆上
作用域: {}
1fn main() { 2 let x:i32 = 1; 3 { 4 let y: i32 = 1; 5 println!("x: {}", x); 6 println!("y: {}", y); 7 }// y被销毁 8} // x会被销毁
String内存回收
移动
clone
堆上分配
code
1fn main() { 2 { 3 // 内存分配 4 let s1 = String::from("hello");// 编译器不知道当前String的大小, 已在后面是可以push_str操作 5 // s1.push_str(" world"); 6 println!("s1: {}", s1); // 输出 hello 7 8 // move 移动 9 let s2 = s1; 10 println!("s2: {}", s2); // 输出 hello 11 println!("s1: {}", s1); // error, 因为此时已经发生了 move 动作,s1的所有权已经给s2了, s1无效了 12 13 // clone 14 let s3 = s2.clone(); 15 println!("s3: {}", s3); // 输出 hello 16 println!("s2: {}", s2); // 输出 hello 17 } 18 19 // 栈上数据拷贝 20}
栈上数据拷贝
copy traint需要实现此特征
常用具有copy traint特征有:
- 所有整型
- 浮点型
- 布尔值
- 字符类型 char
- 元组
1fn main() { 2 3 let a = 1; 4 let b = a; 5 println!("a: {}, b={}", a, b) 6}
函数和作用域
1fn move_ownership(value: String) { 2 println!("move_ownership: {}", value); 3} 4 5fn move_ownership_back(value: String) -> String { 6 println!("move_ownership: {}", value); 7 value 8} 9 10fn copy_value(i: i32) { 11 println!("copy_value: {}", i); 12} 13 14fn main() { 15 let s = String::from("hello"); 16 let s1 = move_ownership_back(s); 17 println!("double get s1: {}", s1); // ok, move后有又将所有权返回了 18 19 move_ownership(s1); 20 println!("double get s: {}", s1); // error 已经发生move了 21 22 let x = 5; // 在栈上 ,具有 copy traint特性,是允许的 23 copy_value(x); 24 println!("double get x: {}", x); // it's ok 25}
引用 &, 借用 & mut
创建一个指向值的应用, 但是不拥有这个值, 所以, 当引用离开其指向的作用域后不会被丢弃
在任意给定时间, 要么只能有一个可变引用, 要么只能有多个不可变的引用
1fn calcute_len(s:&String) -> usize {
2 s.len()
3}
4
5fn update(s: & mut String) {
6 s.push_str(" world");
7}
8fn main() {
9 let mut s1 = String::from("hello");
10 let s = &s1;
11 let len = calcute_len(s);
12 println!("s1: {}", s1);
13 println!("len: {}", len);
借用
1fn calcute_len(s:&String) -> usize {
2 s.len()
3}
4
5fn update(s: & mut String) {
6 s.push_str(" world");
7}
8fn main() {
9 let mut s1 = String::from("hello");
10 let s = &s1;
11 let len = calcute_len(s);
12 println!("s1: {}", s1);
13 println!("len: {}", len);
14
15 // 借用
16 update(&mut s1);
17
18 let r1 = &s1;
19 let r2 = &s1;
20 let r3 = &mut s1;
21 println!("r1: {}, r2: {}, r3: {}", r1, r2, r3); // error, 因为 r3已经法伤mut了 之后又在使用 是不允许的
22
23 let r4 = &s1;
24 let r5 = &s1;
25 println!("r1: {}, r2: {}", r4, r5); // ok
26
27 let r6 = &mut s1;
28 r6.push_str(" world");
29 println!("r1: {}, r2: {}", r4, r5); // error
30 println!("r4: {}, r5: {}, r6: {}", r4, r5, r6); // error, 借用只有 又在使用
31
32}
悬垂引用
1fn main() {
2 let ref_s = dangle(); // ref_s 执行了一个已经回收的内存了
3
4}
5
6fn dange() -> &String {
7 let s = Stirng::from("");
8 &s
9} // s被销毁了
String的slice
1let s = String::from("hello world");
2
3let len = &s[0..=6];
4let len = &s[0..=5];
5let len = &s[..=5];
6let len = &s[2..];
7
8
9let v = String::from("你好");
10let len = &v[0..2]; // error是不允许的的不v
结构体
1fn main() {
2 #[derive(Debug)]
3 struct User {
4 name: String,
5 password: String,
6 }
7
8 let admin = User {
9 name: String::from("admin"),
10 password: String::from("123456"),
11 };
12
13 let mut guest = User {
14 name: String::from("guest"),
15 password: String::from("123456"),
16 };
17
18 guest.password = String::from("guest");
19
20 println!("guest: {:?}", guest);
21
22 let name = String::from("root");
23 let password = String::from("root");
24 let root= User {
25 name,
26 password,
27 };
28 println!("root: {:?}", root);
29
30 let user1 = User {
31 ..admin
32 };
33 println!("user1: {:?}", user1);
34
35 let user2 = User {
36 name: String::from("user2"),
37 ..user1
38 };
39 println!("user2: {:?}", user2);
40 println!("user2: {:#?}", user2);
41
42
43 // 元组结构体
44 // 1. 字段没有名字
45 // 2. 圆括号
46 struct Point(i32, i32);
47
48 let a = Point(10, 20);
49 println!("a.x = {}, a.y={}",a.0, a.1);
50}
Options
// todo
Vector
1let v: Vec<i32> = Vec::new(); // 不能push 是不可变的
2
3let mut vv: Vec<i32> = Vec::new();
4vv.push(1);
5
6let t: i32 = &vv[2]; // 越界 异常了
7
8// 推荐使用方法
9let mut w = vec![1, 2, 3];
10match w.get(1) { // 越界不会异常
11 Some(value)=> println!("value: {}", value);
12 _ => println!("None found");
13}
14
15// 更新
16let mut u: Vec<i32> = Vec::new();
17u.push(1);
18u.push(2);
19u.push(3);
20for i in &u {
21 println!("item: {}", i);
22}
23// mut update
24for i in & mut u {
25 *i += 1;
26}
27// readonly
28for i in &u {
29 println!("item: {}", i);
30}
31
32// 注意 rust规避bug的一种表现
33let mut k = vec![1, 2, 3];
34let first = &k[0]; // 不可变引用
35k.push(6); // 可变引用, 之后不允许在使用不可变引用
36println!("first: {}", first); // error
String
1fn main() {
2 let mut name = String::new();
3 name.push_str("admin"); // 如果不声明 mut 在此处会error
4 let mut pwd = String::from("123456");
5 let pwd1 = "123456abc".to_string();
6 println!("pwd: {}, pwd1: {}", pwd, pwd1);
7
8 pwd.push_str(".");
9 pwd.push('m');
10 // pwd.push('xx'); error
11 // pwd.push("x"); error
12 pwd.push_str(&pwd1);
13 println!("pwd: {}, pwd1: {}", pwd, pwd1);
14
15 let prefix = "t_".to_string();
16 let table = String::from("user");
17
18 let table_name = prefix + &table;
19 println!("table name: {}", table_name);
20 // println!("prefix: {}", prefix); // error , 已经prefix的所有权给 table_name了
21 println!("table: {}", table); // &table是引用, 不会获取所有权 ,所以可以再次使用
22
23 let auth = String::from("guest");
24 let title = String::from("计算机"); // uncode 3个字节 -> 中文
25 // auth[0]; // error
26 let desc = "中国";
27 let a = &desc[0..3];
28 // let b = &desc[0..2]; // error
29 let b = "0";
30 println!("auth len: {}, title: {}, a: {}, b: {}", auth.len(), title.len(), a, b);
31
32 for c in title.chars() {
33 println!("{}", c);
34 }
35 for d in title.bytes() {
36 println!("{}", d);
37 }
38}
HashMap
1use std::collections::HashMap;
2
3fn main() {
4 let mut cache: HashMap<String, i32> = HashMap::new();
5 // 插入数据
6 cache.insert(String::from("admin"), 10);
7 cache.insert(String::from("root"), 20);
8 // key不存在才插入
9 cache.entry(String::from("guest")).or_insert(30);
10 cache.entry(String::from("root")).or_insert(25);
11 println!("{:?}", cache);
12
13 // 遍历插入
14 let keys = vec![String::from("admin"), String::from("root")];
15 let values = vec![10, 20];
16 let data: HashMap<_, _> = keys.iter().zip(values.iter()).collect();
17
18 // get value
19 let search = String::from("admin");
20 let v = data.get(&search);
21 match v {
22 Some(value) => println!("key: {}, value: {}", search, value),
23 _ => println!("Not Found"),
24 }
25
26 if let Some(vvv) = data.get(&search) {
27 println!("key: {}, value: {}", search, vvv);
28 }
29
30 // 遍历
31 for (k, v) in &data {
32 println!("key: {}, value: {}", k, v); // 乱序
33 }
34}
Result
1use std::fs::File;
2
3fn main() {
4 let f = File::open("config.yml");
5 let r = match f {
6 Ok(file) => file,
7 Err(err) => panic!("Couldn't open, {:?}", err),
8 };
9
10 let f = File::open("config.yml").unwrap();
11 let f = File::open("config.yml").expect("Failed to open");
12}
trait & impl & Result
1trait Authorization {
2 fn login(&self) -> Result<&str, String>;
3}
4
5struct UsernamePassword {
6 name: String,
7 password: String,
8}
9
10impl Authorization for UsernamePassword {
11 fn login(&self) -> Result<&str, String> {
12 if self.name == "admin" && self.password == "123456" {
13 return Ok("144-258b-804e-3ac5-c9ebd3485b2f");
14 }
15 return Err("账号密码错误!".to_string());
16 }
17}
18
19fn main() {
20 let user = UsernamePassword {
21 name: "admin".to_string(),
22 password: "123456.".to_string(),
23 };
24 match user.login() {
25 Ok(token) => println!("{}", token),
26 Err(msg) => println!("{}", msg),
27 }
28}
评论