Tuple di Rust
Tuple mengelompokkan beberapa nilai, yang tipenya boleh berbeda-beda, menjadi satu. Ini cara cepat untuk membungkus hal-hal yang saling berkaitan tanpa harus membuat tipe baru untuknya.
Membuat tuple
Section titled “Membuat tuple”fn main() { let person: (&str, i32, bool) = ("Alice", 30, true); println!("{:?}", person);}Output:
("Alice", 30, true)Perhatikan bahwa tuple ini mencampur &str, i32, dan bool dalam satu nilai. Array tidak bisa melakukan ini, karena setiap elemen di dalam array harus bertipe sama.
Untuk mencetak seluruh tuple, pakai {:?} (format debug), bukan {}. {} biasa tidak bisa dipakai untuk tuple.
Mengakses elemen berdasarkan posisi
Section titled “Mengakses elemen berdasarkan posisi”Pakai .0, .1, .2, dan seterusnya. Indeks tuple dimulai dari nol:
fn main() { let person = ("Alice", 30, true);
println!("Nama: {}", person.0); println!("Umur: {}", person.1); println!("Aktif: {}", person.2);}Output:
Nama: AliceUmur: 30Aktif: truePosisinya harus berupa angka biasa yang ditulis langsung di kode. Kamu tidak bisa memakai variabel, seperti person.i, karena setiap posisi bisa menyimpan tipe yang berbeda, dan Rust harus tahu tipenya saat kompilasi.
Destructuring tuple
Section titled “Destructuring tuple”Kamu bisa mengeluarkan setiap nilai ke variabelnya masing-masing dalam satu baris. Ini disebut destructuring (membongkar):
fn main() { let person = ("Alice", 30, true); let (name, age, is_active) = person;
println!("{name} berumur {age}, aktif: {is_active}");}Output:
Alice berumur 30, aktif: trueCara ini sering lebih jelas daripada menulis .0, .1, .2 berulang kali, terutama kalau tuple-nya punya lebih dari dua atau tiga elemen.
Mengembalikan beberapa nilai dari fungsi
Section titled “Mengembalikan beberapa nilai dari fungsi”Tuple adalah cara alami untuk mengembalikan lebih dari satu nilai, karena sebuah fungsi hanya bisa menuliskan satu tipe kembalian:
fn min_max(numbers: &[i32]) -> (i32, i32) { let min = *numbers.iter().min().unwrap(); let max = *numbers.iter().max().unwrap(); (min, max)}
fn main() { let (smallest, largest) = min_max(&[4, 8, 1, 9, 3]); println!("min: {smallest}, maks: {largest}");}Output:
min: 1, maks: 9Jangan khawatir soal &[i32], .iter(), atau .unwrap() dulu. Semuanya dibahas di halaman Slice, Iterator, dan Option. Yang perlu kamu perhatikan di sini adalah tipe kembalian (i32, i32) dan bagaimana main langsung membongkarnya menjadi dua variabel.
Mengubah tuple dan menukar nilai
Section titled “Mengubah tuple dan menukar nilai”Kalau sebuah tuple dideklarasikan dengan mut, kamu bisa mengubah elemennya satu per satu, memakai posisi .0, .1 yang sama. Nilainya boleh berubah, tapi bentuknya tidak: sebuah tuple selalu mempertahankan jumlah dan tipe elemen yang dimilikinya sejak awal.
Destructuring juga bisa dipakai ke arah sebaliknya: kamu bisa memasukkan nilai ke dalam variabel yang sudah ada. Hasilnya adalah cara menukar nilai yang rapi dalam satu baris, tanpa variabel sementara. Kalau kamu hanya butuh sebagian elemen, tulis _ untuk elemen yang tidak kamu perlukan:
fn main() { let mut point = (3, 4); point.0 += 10; // ubah satu elemen secara langsung println!("point sekarang {:?}", point);
let mut a = 1; let mut b = 2; (a, b) = (b, a); // tukar kedua nilai println!("a = {a}, b = {b}");
let (x, _) = point; // simpan x, abaikan elemen kedua println!("x = {x}");}Output:
point sekarang (13, 4)a = 2, b = 1x = 13Penukaran ini berhasil karena Rust membuat sisi kanan, (b, a), lebih dulu. Baru setelah itu Rust membongkarnya ke a dan b. Masih banyak lagi yang bisa kamu lakukan dengan _ dan pola di halaman Pattern matching.
Tuple kosong: ()
Section titled “Tuple kosong: ()”Sebenarnya kamu sudah pernah bertemu sebuah tuple tanpa menyadarinya. () disebut unit type, dan itulah yang dikembalikan sebuah fungsi kalau fungsi itu tidak mengembalikan apa pun yang bermakna. Ini adalah tipe kembalian tersirat dari fn main().
Kapan memakai tuple dan kapan memakai struct
Section titled “Kapan memakai tuple dan kapan memakai struct”Tuple sangat cocok untuk pengelompokan cepat tanpa nama, terutama untuk mengembalikan dua atau tiga nilai dari fungsi. Begitu sekelompok nilai mewakili konsep nyata dengan elemen bernama (seperti Person dengan nama dan umur yang akan kamu sebut berdasarkan namanya di seluruh kode), struct biasanya pilihan yang lebih baik dan lebih mudah dibaca.
Latihan
Section titled “Latihan”1. Jumlah dan hasil kali
Section titled “1. Jumlah dan hasil kali”Tulis fungsi sum_and_product(a: i32, b: i32) -> (i32, i32) yang mengembalikan jumlah sekaligus hasil kali dua angka. Di main, panggil dengan 5 dan 6, lalu bongkar hasilnya. Petunjuk: baris terakhir fungsinya adalah tuple itu sendiri, (a + b, a * b), tanpa titik koma.
Lihat solusi
fn sum_and_product(a: i32, b: i32) -> (i32, i32) { (a + b, a * b)}
fn main() { let (sum, product) = sum_and_product(5, 6); println!("jumlah = {sum}, hasil kali = {product}");}Output:
jumlah = 11, hasil kali = 302. Persegi panjang dari dua sudut
Section titled “2. Persegi panjang dari dua sudut”Sebuah persegi panjang bisa disimpan sebagai tuple berisi dua titik, dan setiap titik juga berupa tuple: let rect = ((1, 2), (5, 5));. Hitung lebar, tinggi, dan luasnya. Petunjuk: tuple bisa bersarang, dan rect.1.0 artinya “elemen pertama dari titik kedua”.
Lihat solusi
fn main() { let rect = ((1, 2), (5, 5));
let width = rect.1.0 - rect.0.0; let height = rect.1.1 - rect.0.1;
println!("lebar {width}, tinggi {height}, luas {}", width * height);}Output:
lebar 4, tinggi 3, luas 12Kamu juga bisa membongkar kedua titik sekaligus: let ((x1, y1), (x2, y2)) = rect;. Memang lebih panjang untuk diketik, tapi x2 - x1 lebih mudah dibaca daripada rect.1.0 - rect.0.0. Kalau titik-titiknya mulai menumpuk seperti ini, itu tanda bahwa struct dengan elemen bernama akan lebih jelas.
Ringkasan
Section titled “Ringkasan”- Tuple mengelompokkan nilai yang tipenya boleh berbeda:
(name, age, is_active). - Akses elemen dengan
.0,.1,.2, atau keluarkan semuanya sekaligus dengan destructuring. - Tuple adalah cara alami untuk mengembalikan beberapa nilai dari fungsi.
- Elemen tuple
mutboleh berubah, tapi ukuran dan tipenya tidak.(a, b) = (b, a);menukar dua nilai. - Untuk pengelompokan bernama yang dipakai berulang kali, pakai struct.
Kuis singkat
Section titled “Kuis singkat”Kuis singkat
1. Apa yang bisa disimpan tuple tapi tidak bisa disimpan array?
2. Bagaimana cara mengakses elemen kedua dari tuple bernama person?
3. Setelah let mut a = 1; let mut b = 2; (a, b) = (b, a);, berapa nilai a dan b?
Skor: 0 / 3
Bacaan lebih lanjut
Section titled “Bacaan lebih lanjut”- The Tuple Type — The Rust Book (bahasa Inggris): pengenalan resmi tentang membuat, membongkar, dan mengakses tuple.
- Tuples — Rust by Example (bahasa Inggris): contoh yang bisa dijalankan dengan tuple bersarang dan tuple sebagai argumen fungsi.
- Tipe
tuple— dokumentasi standard library (bahasa Inggris): trait apa saja yang didukung tuple, seperti membandingkan, menyalin, dan mencetak dengan{:?}. - Tipe
unit— dokumentasi standard library (bahasa Inggris): apa itu()dan di mana ia muncul. - Destructuring assignments — The Rust Reference (bahasa Inggris): aturan persis di balik
(a, b) = (b, a);.