Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

คืนอาร์กิวเมนต์ที่ถูกย้ายความเป็นเจ้าของเมื่อเกิดข้อผิดพลาด

คำอธิบาย

หากฟังก์ชันที่อาจเกิดข้อผิดพลาดได้ (fallible function) มีการย้ายความเป็นเจ้าของ (move/consume) อาร์กิวเมนต์เข้าไปในฟังก์ชัน ให้ส่งคืนอาร์กิวเมนต์ตัวนั้นกลับออกมาภายในข้อมูลข้อผิดพลาด (error) ด้วยเสมอ

ตัวอย่าง

pub fn send(value: String) -> Result<(), SendError> {
    println!("using {value} in a meaningful way");
    // Simulate non-deterministic fallible action.
    use std::time::SystemTime;
    let period = SystemTime::now()
        .duration_since(SystemTime::UNIX_EPOCH)
        .unwrap();
    if period.subsec_nanos() % 2 == 1 {
        Ok(())
    } else {
        Err(SendError(value))
    }
}

pub struct SendError(String);

fn main() {
    let mut value = "imagine this is very long string".to_string();

    let success = 's: {
        // Try to send value two times.
        for _ in 0..2 {
            value = match send(value) {
                Ok(()) => break 's true,
                Err(SendError(value)) => value,
            }
        }
        false
    };

    println!("success: {success}");
}

แรงจูงใจ

เมื่อเกิดข้อผิดพลาดขึ้น คุณอาจต้องการลองใช้วิธีอื่น หรือพยายามทำซ้ำใหม่ (retry) ในกรณีที่ฟังก์ชันนั้นให้ผลลัพธ์ไม่แน่นอน (non-deterministic) ทว่าหากอาร์กิวเมนต์ถูกส่งมอบความเป็นเจ้าของและสูญหายไปทุกครั้งที่เกิดข้อผิดพลาด คุณจะถูกบีบให้ต้องคัดลอกข้อมูล (.clone()) ก่อนเรียกใช้งานเสมอ ซึ่งส่งผลเสียต่อประสิทธิภาพของโปรแกรม

ไลบรารีมาตรฐานของ Rust ใช้แนวทางนี้ในหลายจุด เช่น เมท็อด String::from_utf8 โดยเมื่อส่งเวกเตอร์ของไบต์ที่ไม่ได้ประกอบขึ้นเป็น UTF-8 ที่ถูกต้อง ตัวเมท็อดจะคืนค่าความผิดพลาดเป็น FromUtf8Error ซึ่งคุณสามารถเรียกใช้เมท็อด FromUtf8Error::into_bytes เพื่อนำเวกเตอร์เดิมที่ส่งเข้าไปกลับคืนมาได้

ข้อดี

เพิ่มประสิทธิภาพการทำงานอย่างชัดเจน เนื่องจากสามารถโอนย้ายความเป็นเจ้าของของอาร์กิวเมนต์ได้โดยไม่ต้องกังวลเรื่องการโคลนข้อมูลล่วงหน้า

ข้อเสีย

โครงสร้างของชนิดข้อมูลข้อผิดพลาด (error types) มีความซับซ้อนเพิ่มขึ้นเล็กน้อย