1.错误地使用可变和不可变借用
let mut data = vec![1, 2, 3];let x = &data[0];data.push(4);println!("{}", x);
不能在有不可变引用时修改数据。
2.忘记处理 Option
fn main() { let some_number = Some(5); let sum = some_number + 5; // 错误:Option 类型不能这样直接使用}
使用 match 或 if let 来处理 Option。
let sum = if let Some(n) = some_number { n + 5 } else { 0 };
3.期望的引用而不是实际值
fn foo(x: &i32) { // ...}fn main() { let x = 10; foo(x); // 错误:应传递引用而不是值}
传递引用而不是值。
foo(&x);
4.不匹配的类型
fn main() { let flag = true; let number = if flag { 5 } else { "six" }; // 错误:不匹配的类型}
解决方案:确保所有的分支返回相同的类型。
let number = if flag { 5 } else { 6 };
5.忘记导入trait
use std::io::Write; // 因为 Write trait 已导入fn main() { let mut buffer = Vec::new(); buffer.write_all(b"hello").unwrap(); // 现在可以正常使用 write_all 方法,因为 Write trait 已导入}
必须导入Write trait才能使用其方法。
6.试图在遍历向量的同时修改它
fn main() { let mut vec = vec![1, 2, 3]; for val in &vec { vec.push(*val + 10); // 错误!不能在遍历时修改vec }}
修复: 使用迭代器的.for_each()方法或者先收集需要做的更改,然后再应用它们。
7.不使用可变引用来修改向量中的值
fn main() { let mut vec = vec![1, 2, 3]; for val in vec.iter() { *val *= 2; // 错误!因为`val`是不可变引用 }}
修复: 使用.iter_mut()来获取可变引用。
for val in vec.iter_mut() { *val *= 2;}
8.在向量迭代时错误地使用索引
fn main() { let vec = vec![10, 20, 30]; for i in 0..vec.len() { println!("{}", vec[i]); // 索引方式正确 // 如果修改为 vec[i+1] 就会出错 }}
修复: 确保在使用索引时不要越界。
9.未处理get()返回Option的情况
fn main() { let vec = vec![1, 2, 3]; let val = vec.get(5); // 返回None,因为索引超出范围 println!("{}", val.unwrap()); // 错误!这会panic}
修复: 使用.unwrap_or()或.unwrap_or_else()处理None情况。
let val = vec.get(5).unwrap_or(&0); // 使用默认值println!("{}", val);
10.使用不恰当的迭代器消费方法
fn main() { let vec = vec![1, 2, 3, 4, 5]; let even_numbers: Vec<_> = vec.iter().map(|x| x * 2).collect(); // 正确 let even_number = even_numbers.first().unwrap(); // 尝试获取第一个数 println!("{}", even_number * 2); // 错误!even_number的类型是&&i32}
修复: 在使用值之前进行适当的解引用。
println!("{}", (**even_number) * 2); // 解引用两次到i32
11.在遍历过程中错误地使用for循环去显式创建迭代器
fn main() { let vec = vec![1, 2, 3]; for i in 0..vec.iter().count() { // 错误!不必要的计数和索引 println!("{}", vec[i]); }}
修复: 直接遍历迭代器。
for &val in vec.iter() { println!("{}", val);}
12.忘记引用计数(Rc/Arc)中的借用规则
use std::rc::Rc;let foo = Rc::new(5);let a = *foo;
13.使用*foo应该先调用.clone()去获取Rc里面的值
错误地对字符串切片
let s = String::from("hello");let part = &s[0..2];
字符串索引应该在字符边界处切片。使用.chars()和.bytes()
14.未处理泛型边界
fn print_it<T>(value: T) { println!("{}", value);}
需要为T添加Display trait约束。
15.尝试修改迭代器产生的不可变引用
let mut vector = vec![1, 2, 3];for item in vector.iter_mut() { *item += 10;}
使用iter_mut()来获取可变引用。
16.没有正确使用借用和所有权