New Rust
This commit is contained in:
BIN
Common-Use/hashmap.exe
Normal file
BIN
Common-Use/hashmap.exe
Normal file
Binary file not shown.
BIN
Common-Use/hashmap.pdb
Normal file
BIN
Common-Use/hashmap.pdb
Normal file
Binary file not shown.
26
Common-Use/hashmap.rs
Normal file
26
Common-Use/hashmap.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn thereisnoerror() {
|
||||
let mut map = std::collections::HashMap::new();
|
||||
map.insert("key1", "value1");
|
||||
map.insert("key2", "value2");
|
||||
println!("{:?}", map);
|
||||
}
|
||||
|
||||
fn main(){
|
||||
let mut h = HashMap::new();
|
||||
h.insert(1, "one");
|
||||
h.insert(2, "two");
|
||||
h.insert(3, "three");
|
||||
h.insert(4, "four");
|
||||
h.insert(5, "five");
|
||||
print!("{:?} ", h);
|
||||
//println!("{0}", *h.count(4));
|
||||
let mut a = |y: i64| -> i64 { return 1 + y; };
|
||||
let result = a(3);
|
||||
println!("{}", result);
|
||||
match h.get(&4) {
|
||||
Some(v) => println!("Found: {}", v),
|
||||
None => println!("Not Found"),
|
||||
}
|
||||
}
|
||||
290
Common-Use/readme.md
Normal file
290
Common-Use/readme.md
Normal file
@@ -0,0 +1,290 @@
|
||||
非常好的问题 👏
|
||||
`Option<&V>` 是 Rust 中非常核心的类型之一,理解它对你掌握 **Rust 的所有权系统** 和 **安全编程哲学** 都至关重要。
|
||||
我们来一步步深入讲清楚,从原理到底层实现、再到各种用法与技巧。
|
||||
|
||||
---
|
||||
|
||||
# 🧩 一、什么是 `Option<T>`
|
||||
|
||||
## ✅ 定义
|
||||
|
||||
`Option<T>` 是一个**枚举类型**,定义在标准库中:
|
||||
|
||||
```rust
|
||||
enum Option<T> {
|
||||
Some(T),
|
||||
None,
|
||||
}
|
||||
```
|
||||
|
||||
也就是说,它是一个「可能有值,也可能没有值」的容器。
|
||||
|
||||
* `Some(T)` 表示存在一个值;
|
||||
* `None` 表示值不存在。
|
||||
|
||||
---
|
||||
|
||||
## 🧠 为什么要有 `Option<T>`
|
||||
|
||||
在很多语言(如 C/C++、Java)中,缺失值通常用 `NULL` 或 `None`,但容易出错。
|
||||
Rust 用 `Option<T>` 代替「空指针」,**在类型层面上强制你处理缺失的情况**。
|
||||
这样编译器就能帮你防止空指针错误(`null pointer dereference`)。
|
||||
|
||||
---
|
||||
|
||||
# 🔍 二、`Option<&V>` 是什么?
|
||||
|
||||
在 `HashMap::get()` 等函数中,你会看到返回类型是:
|
||||
|
||||
```rust
|
||||
Option<&V>
|
||||
```
|
||||
|
||||
意思是:
|
||||
|
||||
> “可能返回一个指向值 `V` 的引用,如果 key 不存在,则返回 None。”
|
||||
|
||||
举个例子:
|
||||
|
||||
```rust
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn main() {
|
||||
let mut map = HashMap::new();
|
||||
map.insert("apple", 3);
|
||||
|
||||
let v1 = map.get("apple"); // Some(&3)
|
||||
let v2 = map.get("banana"); // None
|
||||
|
||||
println!("{:?} {:?}", v1, v2);
|
||||
}
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
Some(3) None
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 🧩 三、匹配(模式匹配)方式
|
||||
|
||||
最常见的处理方式是 **match**:
|
||||
|
||||
```rust
|
||||
match map.get("apple") {
|
||||
Some(value) => println!("Found: {}", value),
|
||||
None => println!("Not found"),
|
||||
}
|
||||
```
|
||||
|
||||
这种写法非常直观,但略显冗长,于是 Rust 提供了更优雅的写法👇
|
||||
|
||||
---
|
||||
|
||||
# ⚙️ 四、常见用法大全
|
||||
|
||||
## 1️⃣ `is_some()` / `is_none()`
|
||||
|
||||
判断是否存在值:
|
||||
|
||||
```rust
|
||||
if map.get("apple").is_some() {
|
||||
println!("存在 apple");
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2️⃣ `unwrap()` / `unwrap_or()` / `unwrap_or_default()`
|
||||
|
||||
提取值:
|
||||
|
||||
```rust
|
||||
let v = map.get("apple").unwrap(); // 若 None 则 panic!
|
||||
let v = map.get("apple").unwrap_or(&0); // 若 None 则返回 &0
|
||||
let v = map.get("apple").unwrap_or_default(); // 若 None 则返回默认值
|
||||
```
|
||||
|
||||
> ⚠️ 不建议随意使用 `unwrap()`,除非你确信一定有值。
|
||||
|
||||
---
|
||||
|
||||
## 3️⃣ `if let` 简写匹配
|
||||
|
||||
```rust
|
||||
if let Some(v) = map.get("apple") {
|
||||
println!("数量: {}", v);
|
||||
}
|
||||
```
|
||||
|
||||
比 `match` 简洁,常用于只关心 `Some` 的情况。
|
||||
|
||||
---
|
||||
|
||||
## 4️⃣ `map()` —— 映射转换
|
||||
|
||||
`map()` 能把 `Option` 内的值加工成另一个类型:
|
||||
|
||||
```rust
|
||||
let length = map.get("apple").map(|v| v * 2);
|
||||
println!("{:?}", length); // Some(6)
|
||||
```
|
||||
|
||||
若为 `None`,则结果仍是 `None`。
|
||||
|
||||
---
|
||||
|
||||
## 5️⃣ `and_then()` —— 链式调用
|
||||
|
||||
用于多层 Option 嵌套场景:
|
||||
|
||||
```rust
|
||||
let result = map.get("apple")
|
||||
.and_then(|v| Some(v * 10))
|
||||
.and_then(|x| Some(x + 1));
|
||||
println!("{:?}", result); // Some(31)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6️⃣ `unwrap_or_else()` —— 延迟计算默认值
|
||||
|
||||
```rust
|
||||
let v = map.get("banana").unwrap_or_else(|| {
|
||||
println!("key 不存在,使用默认值");
|
||||
&0
|
||||
});
|
||||
```
|
||||
|
||||
如果 key 不存在,执行闭包生成默认值。
|
||||
|
||||
---
|
||||
|
||||
## 7️⃣ `as_ref()` / `as_mut()`
|
||||
|
||||
将 `Option<T>` 转换为 `Option<&T>` 或 `Option<&mut T>`:
|
||||
|
||||
```rust
|
||||
let opt = Some(String::from("hi"));
|
||||
let ref_opt = opt.as_ref(); // Option<&String>
|
||||
let mut_opt = opt.as_ref(); // Option<&mut String>
|
||||
```
|
||||
|
||||
这在借用时非常实用,尤其是嵌套结构。
|
||||
|
||||
---
|
||||
|
||||
## 8️⃣ `expect()` —— 自定义 panic 信息
|
||||
|
||||
```rust
|
||||
let v = map.get("apple").expect("apple 不存在!");
|
||||
```
|
||||
|
||||
如果是 `None`,会 panic 并显示 `"apple 不存在!"`。
|
||||
|
||||
---
|
||||
|
||||
## 9️⃣ `copied()` / `cloned()`
|
||||
|
||||
如果你要从 `Option<&T>` 提取出 `Option<T>`(复制/克隆),可以这样:
|
||||
|
||||
```rust
|
||||
let map = HashMap::from([("a", 10)]);
|
||||
let val = map.get("a").copied(); // Option<i32>
|
||||
println!("{:?}", val); // Some(10)
|
||||
```
|
||||
|
||||
区别:
|
||||
|
||||
* `.copied()` 要求 `T: Copy`
|
||||
* `.cloned()` 要求 `T: Clone`
|
||||
|
||||
---
|
||||
|
||||
## 🔟 `unwrap_or_default()`
|
||||
|
||||
对简单类型(如 `i32`、`bool`)非常方便:
|
||||
|
||||
```rust
|
||||
let map = HashMap::new();
|
||||
let v: i32 = *map.get("x").unwrap_or_default(); // None -> 默认0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 🧠 五、内部机制(零成本抽象)
|
||||
|
||||
Rust 的 `Option<T>` 在底层通常会被 **编译器优化为“无额外开销”** 的形式。
|
||||
|
||||
举个例子:
|
||||
`Option<&T>` 通常和 `*const T` 的大小完全一样。
|
||||
因为:
|
||||
|
||||
* `None` 会用空指针 `0` 表示;
|
||||
* `Some(x)` 则用非零指针。
|
||||
|
||||
所以:
|
||||
|
||||
```rust
|
||||
std::mem::size_of::<Option<&i32>>() == std::mem::size_of::<&i32>()
|
||||
```
|
||||
|
||||
✅ 成立,说明 `Option<&T>` 没有额外开销。
|
||||
|
||||
---
|
||||
|
||||
# 🧩 六、总结表格
|
||||
|
||||
| 方法 | 作用 | 示例 | | |
|
||||
| --------------------- | -------------------------------- | ------------------------- | - | ----------- |
|
||||
| `is_some()` | 是否有值 | `opt.is_some()` | | |
|
||||
| `is_none()` | 是否为空 | `opt.is_none()` | | |
|
||||
| `unwrap()` | 直接取值(危险) | `opt.unwrap()` | | |
|
||||
| `unwrap_or(x)` | 无值时返回 x | `opt.unwrap_or(0)` | | |
|
||||
| `unwrap_or_default()` | 无值时返回默认值 | `opt.unwrap_or_default()` | | |
|
||||
| `unwrap_or_else(f)` | 无值时调用函数生成 | `opt.unwrap_or_else( | | 0)` |
|
||||
| `expect(msg)` | 无值时 panic,带信息 | `opt.expect("错误")` | | |
|
||||
| `map(f)` | 处理 Some 中的值 | `opt.map( | x | x+1)` |
|
||||
| `and_then(f)` | 链式 Option 处理 | `opt.and_then( | x | Some(x+1))` |
|
||||
| `as_ref()` | 转换为 Option<&T> | `opt.as_ref()` | | |
|
||||
| `as_mut()` | 转换为 Option<&mut T> | `opt.as_mut()` | | |
|
||||
| `copied()` | Option<&T> → Option<T>(T: Copy) | `opt.copied()` | | |
|
||||
| `cloned()` | Option<&T> → Option<T>(T: Clone) | `opt.cloned()` | | |
|
||||
|
||||
---
|
||||
|
||||
# 🔚 七、一个综合示例
|
||||
|
||||
```rust
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn main() {
|
||||
let mut scores = HashMap::new();
|
||||
scores.insert("Alice", 90);
|
||||
scores.insert("Bob", 85);
|
||||
|
||||
let name = "Charlie";
|
||||
let score = scores.get(name)
|
||||
.copied() // Option<i32>
|
||||
.unwrap_or_else(|| {
|
||||
println!("{name} 不存在,使用默认分数");
|
||||
60
|
||||
});
|
||||
|
||||
println!("{name} 的分数是 {score}");
|
||||
}
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
```
|
||||
Charlie 不存在,使用默认分数
|
||||
Charlie 的分数是 60
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
是否希望我接着帮你画一张「`Option<T>` 方法调用关系图(功能导图)」?
|
||||
那张图能直观看出各种方法如何互相转换,非常适合记忆和快速查阅。
|
||||
BIN
Common-Use/vec.exe
Normal file
BIN
Common-Use/vec.exe
Normal file
Binary file not shown.
BIN
Common-Use/vec.pdb
Normal file
BIN
Common-Use/vec.pdb
Normal file
Binary file not shown.
18
Common-Use/vec.rs
Normal file
18
Common-Use/vec.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
fn sum(list:&Vec<i64>) -> i64 {
|
||||
let mut total = 0;
|
||||
for i in list {
|
||||
total += i;
|
||||
}
|
||||
total
|
||||
}
|
||||
|
||||
fn main(){
|
||||
let mut v: Vec<i64> = Vec::new();
|
||||
v.push(1);
|
||||
v.push(2);
|
||||
v.push(3);
|
||||
for i in &v {
|
||||
println!("{}", i);
|
||||
}
|
||||
println!("Sum: {}", sum(&v));
|
||||
}
|
||||
Reference in New Issue
Block a user