Option di Rust
Rust tidak punya null. Kalau sebuah nilai mungkin tidak ada, hal itu dinyatakan langsung di tipenya dengan Option. Awalnya memang terasa seperti formalitas tambahan, tapi cara ini menutup satu kategori bug sepenuhnya: “null reference”, yang sudah menyebabkan crash tak terhitung jumlahnya di bahasa lain.
Bentuk Option
Section titled “Bentuk Option”Option adalah sebuah enum dengan dua varian:
enum Option<T> { Some(T), // ada nilainya None, // tidak ada nilai}Sebenarnya kamu sudah pernah melihatnya: .get() pada vektor dan .get() pada HashMap sama-sama mengembalikan Option.
Membuat Option
Section titled “Membuat Option”fn main() { let has_value: Option<i32> = Some(5); let no_value: Option<i32> = None;
println!("{:?}", has_value); println!("{:?}", no_value);}Output:
Some(5)NoneMenangani Option dengan match
Section titled “Menangani Option dengan match”Cara aman untuk mengambil nilainya adalah dengan match. Rust memaksamu menangani kedua kemungkinan, jadi kamu tidak mungkin tidak sengaja melupakan kasus “tidak ada”:
fn main() { let age: Option<i32> = Some(30);
match age { Some(value) => println!("Umurnya {value}"), None => println!("Umur tidak diisi"), }}Contoh yang lebih nyata
Section titled “Contoh yang lebih nyata”fn find_user(id: u32) -> Option<&'static str> { if id == 1 { Some("Alice") } else { None }}
fn main() { match find_user(1) { Some(name) => println!("Ketemu: {name}"), None => println!("User tidak ditemukan"), }
match find_user(99) { Some(name) => println!("Ketemu: {name}"), None => println!("User tidak ditemukan"), }}Output:
Ketemu: AliceUser tidak ditemukanAlih-alih mengembalikan null atau melempar exception saat user tidak ditemukan, tipe kembalian fungsinya sendiri sudah memberi tahu setiap pemanggil bahwa “fungsi ini mungkin tidak menemukan apa-apa”. Dan compiler tidak akan membiarkan mereka mengabaikan kemungkinan itu.
Jalan pintas: unwrap_or dan unwrap
Section titled “Jalan pintas: unwrap_or dan unwrap”Untuk kasus sederhana, match lengkap bisa terasa berlebihan. Ada beberapa jalan pintas:
fn main() { let age: Option<i32> = None;
let value = age.unwrap_or(0); // pakai 0 sebagai cadangan kalau tidak ada nilai println!("{value}");}Ada juga .unwrap(), yang langsung memberimu nilainya, tapi akan panic (crash) kalau isinya None:
let age: Option<i32> = Some(30);let value = age.unwrap(); // aman di sini, karena age berisi SomeLatihan
Section titled “Latihan”1. Bilangan genap pertama
Section titled “1. Bilangan genap pertama”Tulis fn first_even(numbers: &[i32]) -> Option<i32> yang mengembalikan bilangan genap pertama di dalam slice, atau None kalau tidak ada. Cetak hasilnya untuk [3, 7, 8, 10] dengan match, dan untuk [1, 3, 5] dengan .unwrap_or(0). Petunjuk: lakukan perulangan pada slice dan return Some(n) begitu n % 2 == 0; setelah perulangan selesai, kembalikan None.
Lihat solusi
fn first_even(numbers: &[i32]) -> Option<i32> { for &n in numbers { if n % 2 == 0 { return Some(n); } } None}
fn main() { match first_even(&[3, 7, 8, 10]) { Some(n) => println!("Genap pertama: {n}"), None => println!("Tidak ada bilangan genap"), }
let fallback = first_even(&[1, 3, 5]).unwrap_or(0); println!("Dengan nilai cadangan: {fallback}");}Output:
Genap pertama: 8Dengan nilai cadangan: 02. Mencari sebuah pengaturan
Section titled “2. Mencari sebuah pengaturan”Buat sebuah HashMap berisi pengaturan yang hanya memuat "volume" dengan nilai 80. Lalu lakukan perulangan pada key "volume" dan "kecerahan", dan cetak nilainya kalau ada, atau pesan “belum diatur” kalau tidak ada. Petunjuk: .get(key) pada HashMap mengembalikan Option, jadi kamu bisa langsung melakukan match padanya.
Lihat solusi
use std::collections::HashMap;
fn main() { let mut settings = HashMap::new(); settings.insert("volume", 80);
for key in ["volume", "kecerahan"] { match settings.get(key) { Some(value) => println!("{key} = {value}"), None => println!("{key} belum diatur"), } }}Output:
volume = 80kecerahan belum diaturRingkasan
Section titled “Ringkasan”Option<T>mewakili nilai yang mungkin ada, mungkin juga tidak. Rust tidak punyanull.Some(value)berisi sesuatu;Noneberarti tidak ada apa-apa.matchadalah cara aman untuk menangani kedua kasus; compiler tidak akan membiarkanmu melupakan salah satunya..unwrap_or(default)memberimu nilai cadangan;.unwrap()akan panic kalau nilainyaNone, jadi pakailah seperlunya.
Kuis singkat
Section titled “Kuis singkat”Kuis singkat
1. Apa yang dipakai Rust sebagai pengganti null untuk nilai yang mungkin tidak ada?
2. Apa yang terjadi kalau kamu memanggil .unwrap() pada nilai None?
3. Apa yang dilakukan age.unwrap_or(0) kalau age bernilai None?
4. Kenapa match dianggap cara aman untuk mengambil nilai dari Option?
5. Method mana yang disebut di halaman ini yang sudah mengembalikan Option?
Skor: 0 / 5
Bacaan lebih lanjut
Section titled “Bacaan lebih lanjut”- The Option Enum and Its Advantages Over Null Values — The Rust Book (bahasa Inggris): penjelasan resmi kenapa Rust memakai
Optionalih-alihnull. std::option— dokumentasi standard library (bahasa Inggris): gambaran semua hal yang bisa kamu lakukan denganOption, termasuk method praktis sepertimap,and_then, danis_some.- Option & unwrap — Rust by Example (bahasa Inggris): contoh singkat yang bisa dijalankan tentang
match,unwrap, dan kapan panic terjadi. Option<T>— dokumentasi std (bahasa Inggris): daftar lengkap method-nya, masing-masing dengan contoh kecil yang bisa kamu salin.