柚子快報邀請碼778899分享:Rust|60個新手常犯的錯誤
柚子快報邀請碼778899分享:Rust|60個新手常犯的錯誤
1.錯誤地使用可變和不可變借用
let?mut?data?=?vec![1,?2,?3];
let?x?=?&data[0];
data.push(4);
println!("{}",?x);
不能在有不可變引用時修改數(shù)據(jù)。
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);?//?錯誤:應(yīng)傳遞引用而不是值
}
傳遞引用而不是值。
foo(&x);
4.不匹配的類型
fn?main()?{
????let?flag?=?true;
????let?number?=?if?flag?{?5?}?else?{?"six"?};?//?錯誤:不匹配的類型
}
解決方案:確保所有的分支返回相同的類型。
let?number?=?if?flag?{?5?}?else?{?6?};
5.忘記導(dǎo)入trait
use?std::io::Write;?//?因為?Write?trait?已導(dǎo)入
fn?main()?{
????let?mut?buffer?=?Vec::new();
????buffer.write_all(b"hello").unwrap();
????//?現(xiàn)在可以正常使用?write_all?方法,因為?Write?trait?已導(dǎo)入
}
必須導(dǎo)入Write trait才能使用其方法。
6.試圖在遍歷向量的同時修改它
fn?main()?{
????let?mut?vec?=?vec![1,?2,?3];
????for?val?in?&vec?{
????????vec.push(*val?+?10);?//?錯誤!不能在遍歷時修改vec
????}
}
修復(fù): 使用迭代器的.for_each()方法或者先收集需要做的更改,然后再應(yīng)用它們。
7.不使用可變引用來修改向量中的值
fn?main()?{
????let?mut?vec?=?vec![1,?2,?3];
????for?val?in?vec.iter()?{
????????*val?*=?2;?//?錯誤!因為`val`是不可變引用
????}
}
修復(fù): 使用.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]?就會出錯
????}
}
修復(fù): 確保在使用索引時不要越界。
9.未處理get()返回Option的情況
fn?main()?{
????let?vec?=?vec![1,?2,?3];
????let?val?=?vec.get(5);?//?返回None,因為索引超出范圍
????println!("{}",?val.unwrap());?//?錯誤!這會panic
}
修復(fù): 使用.unwrap_or()或.unwrap_or_else()處理None情況。
let?val?=?vec.get(5).unwrap_or(&0);?//?使用默認(rèn)值
println!("{}",?val);
10.使用不恰當(dāng)?shù)牡飨M方法
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();?//?嘗試獲取第一個數(shù)
????println!("{}",?even_number?*?2);?//?錯誤!even_number的類型是&&i32
}
修復(fù): 在使用值之前進(jìn)行適當(dāng)?shù)慕庖谩?/p>
println!("{}",?(**even_number)?*?2);?//?解引用兩次到i32
11.在遍歷過程中錯誤地使用for循環(huán)去顯式創(chuàng)建迭代器
fn?main()?{
????let?vec?=?vec![1,?2,?3];
????for?i?in?0..vec.iter().count()?{?//?錯誤!不必要的計數(shù)和索引
????????println!("{}",?vec[i]);
????}
}
修復(fù): 直接遍歷迭代器。
for?&val?in?vec.iter()?{
????println!("{}",?val);
}
12.忘記引用計數(shù)(Rc/Arc)中的借用規(guī)則
use?std::rc::Rc;
let?foo?=?Rc::new(5);
let?a?=?*foo;
13.使用*foo應(yīng)該先調(diào)用.clone()去獲取Rc里面的值
錯誤地對字符串切片
let?s?=?String::from("hello");
let?part?=?&s[0..2];
字符串索引應(yīng)該在字符邊界處切片。使用.chars()和.bytes()
14.未處理泛型邊界
fn?print_it
????println!("{}",?value);
}
需要為T添加Display trait約束。
15.嘗試修改迭代器產(chǎn)生的不可變引用
let?mut?vector?=?vec![1,?2,?3];
for?item?in?vector.iter_mut()?{
????*item?+=?10;
}
使用iter_mut()來獲取可變引用。
16.沒有正確使用借用和所有權(quán)
柚子快報邀請碼778899分享:Rust|60個新手常犯的錯誤
文章來源
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。