Skip to content

Commit a906e3f

Browse files
author
baxiang
committed
docs: 补充1-basics语言对比和常见错误诊断
- 03-变量基础:Rust vs Java/C++/Python 对比 + 常见错误(E0384/E0381/E0308) - 05-函数基础:Rust vs Python/JS/Java 对比 + 常见错误(E0416/返回类型/分号错误) - 06-模式匹配:match vs switch 对比 + 常见错误(E0004/类型不一致/if let方向) 强化"编译器是免费导师"理念
1 parent 7b9521f commit a906e3f

3 files changed

Lines changed: 857 additions & 0 deletions

File tree

1-basics/03-variables/01-变量基础.md

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,256 @@ fn main() {
143143
│ │
144144
│ Rust 哲学:让正确的事情变得容易 │
145145
│ │
146+
└───────────────────────────────────────┘
147+
```
148+
149+
---
150+
151+
## 语言对比:变量可变性
152+
153+
### Rust vs 其他语言
154+
155+
```
156+
┌─────────────────────────────────────────────────────┐
157+
│ 变量可变性对比 │
158+
├─────────────────────────────────────────────────────┤
159+
│ │
160+
│ Java/C++: │
161+
│ ├── int x = 5; // 默认可变 │
162+
│ ├── x = 10; // ✅ 允许 │
163+
│ ├── final int y = 5; // 需要显式标记不可变 │
164+
│ └── 设计:可变是默认,不可变需额外声明 │
165+
│ │
166+
│ Python: │
167+
│ ├── x = 5 // 可变 │
168+
│ ├── x = 10 // ✅ 允许 │
169+
│ ├── 无不可变变量语法 │
170+
│ └── 设计:全部可变 │
171+
│ │
172+
│ Rust: │
173+
│ ├── let x = 5; // 默认不可变 │
174+
│ ├── x = 10; // ❌ 编译错误 │
175+
│ ├── let mut y = 5; // 需要显式标记可变 │
176+
│ ├── y = 10; // ✅ 允许 │
177+
│ └── 设计:不可变是默认,可变需额外声明 │
178+
│ │
179+
│ 对比结论: │
180+
│ ├── Java/C++:安全需主动追求 │
181+
│ ├── Python:安全靠自觉 │
182+
│ ├── Rust:安全是默认 │
183+
│ │
184+
└─────────────────────────────────────────────────────┘
185+
```
186+
187+
### 实际代码对比
188+
189+
```rust
190+
// Rust:默认安全
191+
fn main() {
192+
let config = load_config(); // 不可变
193+
// config = new_config(); // ❌ 编译器阻止修改
194+
195+
let mut counter = 0; // 显式声明需要修改
196+
counter += 1; // ✅ 允许
197+
}
198+
```
199+
200+
```java
201+
// Java:需要主动保护
202+
public class Example {
203+
void run() {
204+
int config = loadConfig(); // 可被意外修改
205+
config = newConfig(); // ✅ 允许(可能是 bug)
206+
207+
final int safeConfig = loadConfig(); // 需要显式 final
208+
// safeConfig = newConfig(); // ❌ 编译错误
209+
}
210+
}
211+
```
212+
213+
---
214+
215+
## 常见错误诊断
216+
217+
### 错误 1:修改不可变变量
218+
219+
#### 错误代码
220+
221+
```rust
222+
fn main() {
223+
let x = 5;
224+
x = 10; // 尝试修改不可变变量
225+
}
226+
```
227+
228+
#### 编译器错误
229+
230+
```
231+
error[E0384]: cannot assign twice to immutable variable `x`
232+
--> src/main.rs:3:5
233+
|
234+
2 | let x = 5;
235+
| - first assignment to `x`
236+
3 | x = 10;
237+
| ^^^^^^ cannot assign twice to immutable variable
238+
|
239+
help: make this binding mutable
240+
|
241+
2 | let mut x = 5;
242+
| +++
243+
```
244+
245+
#### 解读错误信息
246+
247+
```
248+
┌─────────────────────────────────────────────────────┐
249+
│ 错误信息解读 │
250+
├─────────────────────────────────────────────────────┤
251+
│ │
252+
│ error[E0384]: cannot assign twice to immutable │
253+
│ variable `x` │
254+
│ │ │
255+
│ │ 错误码 E0384 = "不能给不可变变量赋值两次" │
256+
│ │ x 是不可变的,不能再次赋值 │
257+
│ │
258+
│ first assignment to `x` │
259+
│ │ │
260+
│ │ 说明:第一次赋值位置(let x = 5) │
261+
│ │
262+
│ cannot assign twice to immutable variable │
263+
│ │ │
264+
│ │ 说明:尝试第二次赋值 │
265+
│ │ 原因:变量不可变 │
266+
│ │
267+
│ help: make this binding mutable │
268+
│ │ │
269+
│ │ 建议:添加 mut 使变量可变 │
270+
│ │ 解决方案:let mut x = 5; │
271+
│ │
272+
│ 关键:编译器告诉你原因和解决方案 │
273+
│ │
146274
└─────────────────────────────────────────────────────┘
147275
```
148276

277+
#### 修复方案
278+
279+
```rust
280+
// 方案 1:添加 mut(如果确实需要修改)
281+
fn main() {
282+
let mut x = 5; // 显式声明可变
283+
x = 10; // ✅ 正确
284+
}
285+
286+
// 方案 2:保持不可变(如果不需要修改)
287+
fn main() {
288+
let x = 5;
289+
let x = 10; // 使用变量遮蔽(shadowing)
290+
println!("{}", x);
291+
}
292+
```
293+
294+
---
295+
296+
### 错误 2:未初始化变量
297+
298+
#### 错误代码
299+
300+
```rust
301+
fn main() {
302+
let x: i32;
303+
println!("{}", x); // 使用未初始化变量
304+
}
305+
```
306+
307+
#### 编译器错误
308+
309+
```
310+
error[E0381]: used assignment is required but `x` is not assigned
311+
--> src/main.rs:3:20
312+
|
313+
2 | let x: i32;
314+
| - help: consider assigning a value: `let x: i32 = <value>;`
315+
3 | println!("{}", x);
316+
| ^ used assignment is required but `x` is not assigned
317+
```
318+
319+
#### 解读与修复
320+
321+
```
322+
错误码 E0381:使用了未赋值的变量
323+
324+
修复:
325+
├── 方案 1:初始化变量
326+
│ let x: i32 = 0;
327+
328+
├── 方案 2:使用类型推断(自动推断为 0)
329+
│ let x = 0;
330+
```
331+
332+
---
333+
334+
### 错误 3:类型不匹配
335+
336+
#### 错误代码
337+
338+
```rust
339+
fn main() {
340+
let x: i32 = "hello";
341+
}
342+
```
343+
344+
#### 编译器错误
345+
346+
```
347+
error[E0308]: mismatched types
348+
--> src/main.rs:2:18
349+
|
350+
2 | let x: i32 = "hello";
351+
| ^^^^^^^ expected `i32`, found `&str`
352+
|
353+
= note: expected type `i32`
354+
found reference `&str`
355+
```
356+
357+
#### 解读与修复
358+
359+
```
360+
错误码 E0308:类型不匹配
361+
362+
原因:
363+
├── 声明类型:i32(整数)
364+
├── 实际类型:&str(字符串)
365+
├── 类型不兼容
366+
367+
修复:
368+
├── 方案 1:修改值类型
369+
│ let x: i32 = 42;
370+
371+
├── 方案 2:修改声明类型
372+
│ let x: &str = "hello";
373+
```
374+
375+
---
376+
377+
### 错误诊断速查
378+
379+
| 错误码 | 错误类型 | 原因 | 快速解决 |
380+
|--------|---------|------|---------|
381+
| E0384 | 修改不可变变量 | 尝试给 `let` 变量赋值两次 | 添加 `mut` |
382+
| E0381 | 未初始化变量 | 使用未赋值的变量 | 初始化变量 |
383+
| E0308 | 类型不匹配 | 值与声明类型不符 | 修正类型 |
384+
385+
---
386+
387+
## 小结
388+
389+
本章核心:
390+
391+
- `let` 声明变量,默认不可变
392+
- `let mut` 声明可变变量
393+
- Rust 默认不可变,主动追求安全
394+
- 编译器错误是最好的学习线索
395+
149396

150397

151398

0 commit comments

Comments
 (0)