Result

Nestero
Bismillahirrahmanirrahim

Apa itu Result ?

Sederhananya Result pada rust adalah sebuah enum yang memiliki dua varian kemungkinan. Result digunakan untuk mengembalikan nilai dari sebuah fungsi yang berpotensi gagal.

enum Result<T, E> {
	Ok(T),
	Err(E),
}
// Ok(T) Menandakan sukses atau berhasil, dan membungkus hasil yang diinginkan dengan tipe data tertentu (T).
// Err(E) Menandakan error atau gagal, dan membungkus informasi kesalahan dengan tipe data tertentu (E).

contoh

// T (sukses) adalah f64
// E (error) adalah String
fn pembagian(pembilang: f64, penyebut: f64) -> Result<f64, String> {
	if penyebut == 0.0 {
		// mengembalikan varian Err
		return Err(String::from("Tidak bisa membagi dengan nol!"));
	}
	// mengembalikan varian Ok
	Ok(pembilang / penyebut)
}

fn main() {
	let hasil = pembagian(10.0, 2.0);
	match hasil {
		Ok(nilai) => println!("Berhasil, nilainya : {}", nilai),
		Err(pesan_err) => println!("Gagal, karena : {}", pesan_err)
	}
}

Operator ?

Cara idiomatik di rust untuk kode yang lebih bersih. Jika fungsi mengembalikan result, bisa menggunakan operator ? di akhir pemanggilan fungsi.

  • Jika hasilnya Ok, maka nilai langsung diambil.
  • Jika hasilnya Err, maka error tersebut akan langsung direturn.

contoh

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

// fungsi ini mencoba membaca isi file menjadi string
fn baca_file_teks(path: &str) -> Result<String, io::Error> {
	// coba buka file jika gagal, error langsung dikembalikan.
	let mut file = File::open(path)?; 

	let mut isi = String::new();
	// coba baca jika gagal, error langsung dikembalikan.
	file.read_to_string(&mut isi)?;

	Ok(isi)
}

Unwrapping

Fungsi - fungsi berikut ini digunakan untuk mengambil nilai Ok secara langsung, namun dengan risiko panic jika nilainya Err.

  • unwrap() : Langsung mengambil nilai Ok dan akan panic jika Err.
  • expect(pesan_error) : Sama seperti unwrap, tetapi menampilkan pesan error saat panic.
  • unwrap_or(default): Lebih aman jika Err maka akan mengembalikan nilai cadangan yang diberikan.
let hasil = pembagian(10.0, 0.0).unwrap(); 
// program akan crash, karena pembagian dengan nol.

let hasil2 = pembagian(10.0, 0.0).expect("error saat membagi!");
// program akan crash dan menampilkan pesan "error saat membagi!"

let hasil3 = pembagian(10.0, 0.0).unwrap_or(0.0); // jika error, nilai menjadi 0.0

unwrap_or_default dan unwrap_or_else

Cara lain untuk menangani nilai default dengan lebih fleksibel.

  • unwrap_or_default() : Jika Err, mengembalikan nilai default dari tipe data tersebut (misal 0 untuk integer dan "" untuk string). Tipe data harus mengimplementasikan trait Default.
  • unwrap_or_else(closure) : Jika Err, jalankan fungsi (closure) untuk nilai pengganti. Ini lebih efisien daripada unwrap_or.
let hasil = pembagian(10.0, 0.0);
// f64 mengimplementasikan trait Default, nilainya adalah 0.0
let nilai_default = hasil.unwrap_or_default(); // output: 0

let hasil_2 = pembagian(10.0, 0.0);
let nilai_alternatif = hasil_2.unwrap_or_else(|pesan_error| {
		println!("Error: {}", pesan_error);
		println!("Mengembalikan nilai fallback (1.0)...");

		// mengembalikan nilai alternatif
		1.0 
}); // output: 1

Lainnya

Berikut adalah fungsi lain yang sering digunakan untuk mengecek status atau mengubah tipe Result.

Pengecekan Status (is_ok & is_err)

Untuk mengecek apakah varian adalah Ok atau Err tanpa mengambil nilainya bisa menggunakan is_ok dan is_err, => akan mengembalikan boolean.

let hasil = pembagian(10.0, 2.0);
// mengecek apakah hasil sukses
if hasil.is_ok() {
	// aman melakukan unwrap karena sudah pasti Ok
	println!("Nilainya adalah: {}", hasil.unwrap());
}

let hasil_2 = pembagian(5.0, 0.0);
// mengecek apakah terjadi error
if hasil.is_err() {
	// tidak boleh unwrap() di sini, karena akan panic
	println!("Error ??? ")
}

// mengecek kebalikannya (is_ok pada error)
if !hasil_2.is_ok() {
     println!("(Konfirmasi: Hasil ini memang Err)");
}

let hasil_3 = pembagian(10.0, 2.0);
// cek jika Ok dan nilainya lebih besar dari 3.0
if hasil_3.is_ok_and(|nilai| nilai > 3.0) {
    println!("Sukses dan nilainya valid di atas 3.0!");
}

Konversi ke Option (ok & err)

Mengubah result menjadi option agar lebih mudah diproses jika tidak peduli dengan detail errornya, bisa menggunakan fungsi ok dan err.

// ok
let hasil = pembagian(10.0, 2.0)
// konversi ke option
let option_hasil: Option<f64> = hasil.ok(); // output: Some(5.0) atau jika Err maka bernilai None

// err, ini kebalikannya dengan ok,
// jika ok akan fokus ke hasil dari Oknya sedangan err akan mengabaikan jika Ok dan fokus ke Err.
let hasil_2 = pembagian(10.0, 0.0)
// output: Some("Tidak bisa membagi dengan nol!") atau jika Ok maka bernilai None
let option_hasil_2: Option<String> = hasil_2.err(); 

Referensi (as_ref)

as_ref() sangat berguna ketika ingin melakukan operasi pada result tanpa mengambil kepemilikan (ownership). Mengubah Result<T, E> menjadi Result<&T, &E>.

let hasil = pembagian(10.0, 2.0);

// dari Result<f64, String> mendjadi Result<&f64, &String>
let referensi = hasil.as_ref();
match referensi {
		Ok(n) => println!("nilai: {}", n), 
		Err(e) => println!("error: {}", e),
}

Perbedaan Result dan Option

FiturResultOption
VarianOk(T), Err(E)Some (T), None
KegunaanOperasi yang bisa gagal (error)Nilai mungkin ada atau tidak ada
Sesungguhnya yang menyebabkan ilmu hilang adalah lupa dan tidak mengulanginya.

"Sesungguhnya yang menyebabkan ilmu hilang adalah lupa dan tidak mengulanginya."

Imam Az-Zuhri rahimahullah

Tags:

Referensi:

Catatan Terkait:

NESTECH ID

Copyright 2025. All rights reserved.