0Pricing
Learn Rust Coding · Pelajaran

Penanganan Galat yang Tangguh dengan `Result`

Terapkan penanganan galat idiomatis menggunakan enum `Result`, operator `?`, dan tipe galat khusus untuk aplikasi yang tangguh.

Penanganan Galat yang Tangguh dengan `Result` adalah pelajaran Learn Rust Coding gratis di CoddyKit. Ini adalah pelajaran 3 dari 3. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Learn Rust Coding, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Learn Rust Coding mencakup 3 pelajaran total.

Menangani Error dalam Rust

Error adalah bagian dari pemrograman. Dalam Rust, kita membedakan dua jenis utama: error yang dapat dipulihkan dan yang tidak dapat dipulihkan.

  • Error yang tidak dapat dipulihkan biasanya menandakan bug sehingga program berhenti dengan panic!.
  • Error yang dapat dipulihkan berarti terjadi kesalahan, tetapi kesalahan tersebut dapat ditangani, misalnya file tidak ditemukan.

Rust membantu Anda menangani error yang dapat dipulihkan dengan baik.

`panic!` vs `Result`

Saat terjadi error yang tidak dapat dipulihkan, Rust memanggil makro panic!. Makro ini membatalkan stack dan mengakhiri program Anda, biasanya dengan mencetak pesan error.

Untuk error yang dapat dipulihkan, Rust menggunakan enumerasi Result. Enumerasi ini memberi tahu Anda apakah suatu operasi berhasil (Ok) atau gagal (Err), sehingga program Anda dapat menentukan tindakan berikutnya.

Enumerasi `Result`

Enumerasi Result secara konseptual didefinisikan sebagai berikut:

enum Result<T, E> {
  Ok(T),
  Err(E),
}

  • T mewakili jenis nilai yang dikembalikan saat berhasil.
  • E mewakili jenis error yang dikembalikan saat gagal.

Ini adalah cara yang ampuh untuk menyatakan secara eksplisit bahwa suatu fungsi mungkin gagal.

Pencocokan pada `Result`

Cara yang paling umum untuk menangani Result adalah menggunakan ekspresi match. Dengan cara ini, Anda dapat menjalankan blok kode yang berbeda berdasarkan apakah Result bernilai Ok atau Err.

Cobalah menjalankan contoh yang mencoba mengurai sebuah angka ini:

fn parse_and_add(text: &str) -> Result<i32, std::num::ParseIntError> {
    text.parse::<i32>()
}

fn main() {
    let num_str = "123";
    let result = parse_and_add(num_str);

    match result {
        Ok(num) => println!("Parsed number: {}", num),
        Err(e) => println!("Error parsing: {}", e),
    }

    let bad_str = "abc";
    let bad_result = parse_and_add(bad_str);

    match bad_result {
        Ok(num) => println!("Parsed number: {}", num),
        Err(e) => println!("Error parsing: {}", e),
    }
}

Membuka Bungkus Result dengan Hati-Hati!

Terkadang Anda mungkin yakin bahwa suatu operasi tidak akan gagal, atau Anda ingin program berhenti jika operasi tersebut gagal. Method seperti unwrap() dan expect() mengambil nilai Ok.

  • unwrap(): Mengembalikan nilai Ok atau memicu panic jika nilainya Err.
  • expect("message"): Sama seperti unwrap(), tetapi memungkinkan Anda memberikan pesan panic khusus.

Gunakan method ini secara terbatas, terutama dalam pengujian atau saat kegagalan benar-benar tidak dapat dipulihkan.

Memperkenalkan Operator `?`

Menulis pernyataan match untuk setiap Result dapat menjadi berulang. Operator ? menyediakan cara singkat untuk meneruskan error.

Jika ditempatkan setelah ekspresi yang mengembalikan Result, ? melakukan dua hal:

  • Jika Result bernilai Err, operator ini segera mengembalikan Err dari fungsi saat ini.
  • Jika Result bernilai Ok, operator ini membuka bungkus nilai Ok dan melanjutkan eksekusi.

Operator `?` dalam Praktik

Operator ? membuat fungsi yang mungkin gagal menjadi jauh lebih bersih untuk ditulis. Ingat, fungsi yang menggunakan ? harus mengembalikan Result (atau Option) itu sendiri.

Perhatikan bagaimana ? menyederhanakan penanganan error dalam contoh pembacaan file berikut:

use std::fs::File;
use std::io::{self, Read};

fn read_username_from_file() -> Result<String, io::Error> {
    let mut f = File::open("hello.txt")?; // Propagates error if file not found
    let mut s = String::new();
    f.read_to_string(&mut s)?; // Propagates error if read fails
    Ok(s)
}

fn main() {
    // Create a dummy file for the example to work
    // In a real scenario, this file might not exist
    std::fs::write("hello.txt", "CoddyKit User").unwrap();

    match read_username_from_file() {
        Ok(username) => println!("Username: {}", username),
        Err(e) => println!("Error reading username: {}", e),
    }

    // Clean up the dummy file
    std::fs::remove_file("hello.txt").unwrap();
}

Jenis Error Kustom

Terkadang, jenis error bawaan tidak cukup spesifik. Anda dapat mendefinisikan jenis error kustom sendiri menggunakan enumerasi untuk merepresentasikan berbagai kemungkinan kegagalan dalam aplikasi Anda.

Dengan begitu, pesan error menjadi lebih jelas dan pemanggil dapat menangani error tertentu dengan cara yang berbeda.

Pola yang umum adalah membuat enumerasi yang mencantumkan semua kemungkinan error yang dapat dihasilkan oleh suatu fungsi atau modul.

Membuat `?` Berfungsi dengan Error Kustom

Agar operator ? dapat secara otomatis mengonversi error tingkat rendah (seperti io::Error) menjadi jenis error kustom Anda, enumerasi error kustom tersebut harus mengimplementasikan trait From untuk error tingkat rendah itu.

Hal ini memberi tahu Rust cara mengonversi satu jenis error menjadi jenis lainnya sehingga penerusan error berlangsung lancar.

use std::io;
use std::fs::File;
use std::io::Read;

#[derive(Debug)]
enum MyError {
    Io(io::Error),
    Parse(std::num::ParseIntError)
}

impl From<io::Error> for MyError {
    fn from(error: io::Error) -> Self {
        MyError::Io(error)
    }
}

impl From<std::num::ParseIntError> for MyError {
    fn from(error: std::num::ParseIntError) -> Self {
        MyError::Parse(error)
    }
}

fn read_config(path: &str) -> Result<i32, MyError> {
    let mut file = File::open(path)?; // io::Error converted to MyError::Io
    let mut contents = String::new();
    file.read_to_string(&mut contents)?; // io::Error converted to MyError::Io
    let value = contents.trim().parse::<i32>()?; // ParseIntError converted to MyError::Parse
    Ok(value)
}

fn main() {
    // Create a dummy file for the example
    std::fs::write("config.txt", "123").unwrap();

    match read_config("config.txt") {
        Ok(val) => println!("Config value: {}", val),
        Err(e) => println!("Failed to read config: {:?}", e),
    }

    std::fs::remove_file("config.txt").unwrap(); // Clean up

    // Example with a non-existent file
    match read_config("non_existent.txt") {
        Ok(val) => println!("Config value: {}", val),
        Err(e) => println!("Failed to read config: {:?}", e),
    }
}

Uji Pemahaman Anda

Perhatikan potongan kode Rust berikut. Apa outputnya jika file data.txt TIDAK ada?

Ringkasan: Penanganan Error yang Kuat

Anda telah menguasai penanganan error yang kuat dalam Rust!

  • Enumerasi Result: Membedakan Ok(T) untuk keberhasilan dan Err(E) untuk kegagalan.
  • match: Cara dasar untuk menangani varian Result.
  • Operator ?: Jalan pintas yang ampuh untuk meneruskan nilai Err ke atas tumpukan pemanggilan.
  • Error Kustom: Mendefinisikan jenis error sendiri menggunakan enumerasi agar lebih jelas dan dapat ditangani secara spesifik.
  • Trait From: Memungkinkan konversi error tingkat rendah menjadi jenis error kustom secara lancar saat menggunakan ?.

Selanjutnya, jelajahi fitur sistem tipe tingkat lanjut!

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Penanganan Galat yang Tangguh dengan `Result`” gratis?

Ya — teks lengkap “Penanganan Galat yang Tangguh dengan `Result`” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Learn Rust Coding, upgrade ke CoddyKit PRO. Kursus Learn Rust Coding mencakup 3 pelajaran total.

Apa yang akan aku pelajari di “Penanganan Galat yang Tangguh dengan `Result`”?

Terapkan penanganan galat idiomatis menggunakan enum `Result`, operator `?`, dan tipe galat khusus untuk aplikasi yang tangguh. Kamu berlatih Learn Rust Coding dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Learn Rust Coding?

Tidak diperlukan pengalaman sebelumnya. Learn Rust Coding di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 3.

Berapa lama pelajaran “Penanganan Galat yang Tangguh dengan `Result`” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Learn Rust Coding ini?

Ya. Setiap pelajaran Learn Rust Coding menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Mengatur Kode dengan Modul
  2. Mengelola Dependensi dengan Crate
  3. Penanganan Galat yang Tangguh dengan `Result`
← Kembali ke Learn Rust Coding