ฉันกำลังอ่านเอกสารสำหรับFile
:
//..
let mut file = File::create("foo.txt")?;
//..
อะไรคือสิ่งที่?
อยู่ในแนวเดียวกันนี้หรือไม่? ฉันจำไม่ได้ว่าเคยเห็นมันใน Rust Book มาก่อน
ฉันกำลังอ่านเอกสารสำหรับFile
:
//..
let mut file = File::create("foo.txt")?;
//..
อะไรคือสิ่งที่?
อยู่ในแนวเดียวกันนี้หรือไม่? ฉันจำไม่ได้ว่าเคยเห็นมันใน Rust Book มาก่อน
คำตอบ:
ดังที่คุณอาจสังเกตเห็น Rust ไม่มีข้อยกเว้น มีอาการตื่นตระหนก แต่ฟังก์ชันการทำงานมี จำกัด (ไม่สามารถนำข้อมูลที่มีโครงสร้างได้) และไม่แนะนำให้ใช้เพื่อจัดการข้อผิดพลาด (มีไว้สำหรับข้อผิดพลาดที่ไม่สามารถกู้คืนได้)
ใน Rust Result
จัดการข้อผิดพลาดการใช้งาน ตัวอย่างทั่วไปจะเป็น:
fn halves_if_even(i: i32) -> Result<i32, Error> {
if i % 2 == 0 {
Ok(i / 2)
} else {
Err(/* something */)
}
}
fn do_the_thing(i: i32) -> Result<i32, Error> {
let i = match halves_if_even(i) {
Ok(i) => i,
Err(e) => return Err(e),
};
// use `i`
}
สิ่งนี้ยอดเยี่ยมเพราะ:
อย่างไรก็ตามมันน้อยกว่าอุดมคติ แต่มันเป็นเรื่องฟุ่มเฟือยมาก นี่คือที่?
มาของตัวดำเนินการเครื่องหมายคำถาม
ข้างต้นสามารถเขียนใหม่เป็น:
fn do_the_thing(i: i32) -> Result<i32, Error> {
let i = halves_if_even(i)?;
// use `i`
}
ซึ่งกระชับกว่ามาก
สิ่ง?
ที่เทียบเท่ากับmatch
ข้อความข้างต้น กล่าวโดยย่อ: มันจะเปิดกล่องResult
if OK และส่งคืนข้อผิดพลาดหากไม่
มันเป็นความมหัศจรรย์เล็กน้อย แต่จัดการข้อผิดพลาดความต้องการความมหัศจรรย์บางอย่างที่จะตัดลงสำเร็จรูปและแตกต่างจากข้อยกเว้นมันจะมองเห็นได้ทันทีซึ่งฟังก์ชั่นการโทรหรืออาจจะไม่เกิดข้อผิดพลาดออก: ?
ผู้ที่จะประดับด้วย
ตัวอย่างหนึ่งของเวทมนตร์คือสิ่งนี้ใช้ได้กับOption
:
// Assume
// fn halves_if_even(i: i32) -> Option<i32>
fn do_the_thing(i: i32) -> Option<i32> {
let i = halves_if_even(i)?;
// use `i`
}
นี้เป็นที่ขับเคลื่อนโดย (ไม่แน่นอน) Try
ลักษณะ
ดูสิ่งนี้ด้วย:
Result
Option
สำหรับการเผยแพร่ข้อผิดพลาดสำหรับประเภทข้อผิดพลาดที่กู้คืนได้ผลลัพธ์ <T, E> มันแกะผลลัพธ์และให้คุณค่าภายในแก่คุณ
แทนที่จะจัดการกรณีข้อผิดพลาดคุณเผยแพร่ไปยังรหัสผู้โทรและจัดการเฉพาะกรณีตกลง ข้อดีคือช่วยกำจัดหม้อไอน้ำจำนวนมากและทำให้การใช้งานฟังก์ชันง่ายขึ้น
.unwrap()
ตื่นตระหนกในกรณีที่เกิดข้อผิดพลาด