Menangani Result dengan match selalu sah, tetapi menulis dua cabang untuk setiap pemanggilan parsing membuat kode cepat membengkak — padahal banyak titik di mana kita yakin hasilnya pasti sukses. Membaca konfigurasi yang barusan kita tulis sendiri di baris atas program, atau menguji satu fungsi kecil di skrip latihan, tidak selalu membutuhkan upacara match lengkap. Rust menyediakan dua pintasan untuk kondisi tersebut: method unwrap() yang mengambil isi Ok secara langsung, dan method expect() yang melakukan hal sama dengan tambahan pesan konteks milik kita. Kedua pintasan punya harga yang sama: bertemu Err berarti panic. Pada chapter ini kita akan menguji kedua wajahnya — jalur sukses yang legawa dan jalur gagal yang meledak — agar kita tahu kapan pintasan ini alat yang tepat.
Mengambil Isi Ok Secara Langsung dengan unwrap #
Method unwrap() membuka bungkus Result dengan satu gerakan: bila isinya Ok(nilai), nilai keluar dan siap dipakai; bila isinya Err, program panic. Program berikut memparse dua masukan yang berhasil dan mencetak hasilnya:
fn main() {
let usia: u32 = "34".parse().unwrap();
println!("Usia terbaca lewat unwrap: {}", usia);
let suhu: f64 = "36.5".parse().expect("Suhu harus berupa angka desimal");
println!("Suhu terbaca lewat expect: {}", suhu);
}Output yang Dihasilkan:
Usia terbaca lewat unwrap: 34
Suhu terbaca lewat expect: 36.5Mari kita bedah kode di atas:
- Baris 2 (
let usia: u32 = "34".parse().unwrap();): anotasi tipeu32memberi tahuparsetipe tujuan konversi. Teks"34"valid, sehinggaparsemenghasilkanOk(34);unwrap()mengeluarkan angka34dan mengikatnya ke variabelusia— tipeusiaadalahu32polos, bukanResult, karena bungkusnya sudah dibuka. - Baris 5 (
let suhu: f64 = "36.5".parse().expect(...)): pola yang sama untuk angka desimal, kali ini denganexpectyang menerima pesan"Suhu harus berupa angka desimal". Karena"36.5"valid, pesan tersebut tidak pernah terpakai dan36.5keluar sebagai nilaif64. - Perhatikan hasil akhir kedua baris: tanpa
match, tanpa cabangErr, kode tetap memperoleh angka siap pakai — inilah daya tarik pintasan: keringkasanunwrapmenyerap seluruh tipeResultdan mengembalikan isiOk-nya saja.
Pada jalur sukses, unwrap dan expect berperilaku identik. Perbedaan keduanya baru muncul saat kegagalan terjadi — dan perbedaan tersebut cukup besar untuk menentukan pilihan kita.
Ketika unwrap Bertemu Err #
Wajah kedua unwrap perlu kita lihat sendiri agar tidak menjadi kebiasaan buta. Program berikut memparse teks "empat puluh" — teks yang jelas bukan angka:
fn main() {
let usia: u32 = "empat puluh".parse().unwrap();
println!("Usia terbaca: {}", usia);
}Pesan panic saat program berjalan:
thread 'main' (1958) panicked at main.rs:2:43:
called `Result::unwrap()` on an `Err` value: ParseIntError { kind: InvalidDigit }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtraceMari kita urai kejadiannya:
- Baris 2 (kolom 43, titik panic):
parsemenghasilkanErr(ParseIntError)karena"empat puluh"berisi huruf;unwrap()menemukanErrdan memicu panic tepat di posisi pemanggilannya. calledResult::unwrap()on anErrvalue: pesan bawaan dariunwrap— seragam untuk semua tipeResult. Pesan ini menyebut tindakan yang salah (unwrap), tetapi tidak menyebut operasi bisnis apa yang sedang berjalan.ParseIntError { kind: InvalidDigit }: isiErrdicetak dengan format{:?}. Format ini menampilkan struktur mentah error — kita mendapat jenis kegagalannya, tetapi tanpa kalimat yang menjelaskan konteks aplikasi.- Baris 3 (
println!): tidak pernah tercetak; panic menghentikanmainsebelum baris ini dieksekusi.
Pesan called Result::unwrap() on an Err value memiliki kelemahan praktis: ketika program besar kita panic di tengah malam, pesan tersebut tidak membantu sama sekali untuk menjawab “operasi apa yang gagal?”. Di titik inilah expect mengambil peran.
expect dengan Pesan yang Berarti #
Method expect() menerima satu argumen teks yang menjadi awal pesan panic. Kita ulangi kegagalan yang sama, kali ini dengan expect:
fn main() {
let usia: u32 = "empat puluh".parse().expect("Usia harus berupa angka");
println!("Usia terbaca: {}", usia);
}Pesan panic saat program berjalan:
thread 'main' (1952) panicked at main.rs:2:43:
Usia harus berupa angka: ParseIntError { kind: InvalidDigit }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtracePerbandingannya langsung terlihat. Bagian pertama pesan kini berbunyi Usia harus berupa angka — kalimat yang kita tulis sendiri dan langsung menunjuk konteks bisnis; bagian kedua tetap berisi ParseIntError { kind: InvalidDigit } dari isi Err. Pola umumnya: expect menulis pesan_kita: isi_err, unwrap menulis called Result::unwrap() on an Err value: isi_err. Alamat main.rs:2:43 pada kedua contoh juga identik karena kedua pemanggilan berada di titik yang sama.
Kapan Pintasan Ini Layak Dipakai #
Keberadaan unwrap dan expect bukan undangan untuk membuka semua Result secara membabi buta. Pedoman berikut membantu menempatkan keduanya:
- Kode latihan dan prototipe: pintasan mempercepat eksperimen; kalau meledak, kita perbaiki saat itu juga.
- Kontrak yang terjamin: teks yang baru kita bangun di baris atas kode — misalnya
String::from("8080").parse()— memang tidak mungkin gagal;expectdengan pesan asumsi menandai jaminan tersebut. - Kondisi yang dianggap bug fatal: bila satu-satunya reaksi yang benar atas kegagalan adalah “program rusak, hentikan”, panic lewat
expectjustru jujur. - Pengujian: dalam test,
expectmembuat kegagalan test langsung terbaca penyebabnya.
Satu pertengkaran teknis kecil perlu kita luruskan: keduanya sering dianggap “anti-pattern”. Yang benar, masalahnya bukan pada method-nya, melainkan pada pemilihan kategori kegagalan. expect di tempat yang tepat adalah kode yang jujur tentang asumsinya; unwrap di jalur masukan pengguna adalah bug menunggu jadwal meledak.
Ringkasan #
unwrap() membuka Result dan mengembalikan isi Ok dalam satu gerakan, sementara expect("pesan") melakukan hal yang sama dengan tambahan pesan konteks yang muncul di awal pesan panic. Kedua method memicu panic saat bertemu Err — unwrap dengan pesan generik called Result::unwrap() on an Err value, expect dengan kalimat milik kita. Pintasan ini layak untuk kode latihan, asumsi yang dijamin kode sendiri, dan test; data eksternal tetap wajib ditangani lewat match atau keluarga unwrap_or. Baik unwrap maupun expect memangkas seluruh cabang gagal — padahal sering kali kita ingin program tetap hidup dengan nilai cadangan. Kebutuhan tersebut dijawab oleh keluarga unwrap_or pada chapter berikutnya.