@@ -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