Fungsi #
Fungsi adalah blok kode yang dapat digunakan kembali untuk melakukan tugas tertentu. Di Rust, fungsi adalah unit dasar dari abstraksi dan organisasi kode, dan mereka digunakan untuk membagi program menjadi bagian-bagian yang lebih kecil dan lebih mudah dikelola. Rust memungkinkan Anda untuk mendefinisikan fungsi dengan parameter, nilai kembalian, dan tipe, serta mendukung berbagai konsep seperti fungsi anonim, fungsi generik, dan closure.
Definisi Fungsi #
Fungsi di Rust didefinisikan menggunakan kata kunci fn
, diikuti oleh nama fungsi, parameter (jika ada), dan tipe nilai kembalian (jika ada). Jika fungsi tidak mengembalikan nilai, tipe nilai kembalian bisa diabaikan atau dinyatakan sebagai ()
(unit type).
Sintaks Dasar:
fn nama_fungsi(parameter: Tipe) -> TipeKembalian {
// Blok kode
}
Contoh Sederhana:
fn greet(name: &str) {
println!("Hello, {}!", name);
}
fn main() {
greet("Alice");
}
Penjelasan:
- Fungsi
greet
menerima satu parametername
dari tipe&str
dan tidak mengembalikan nilai. - Di dalam
main
, fungsigreet
dipanggil dengan argumen"Alice"
.
Parameter dan Argumen #
Fungsi di Rust dapat memiliki parameter, yang digunakan untuk menerima input dari pemanggil fungsi. Setiap parameter harus memiliki tipe yang eksplisit, karena Rust adalah bahasa pemrograman yang secara kuat mengetikkan (strongly-typed).
Contoh Fungsi dengan Parameter:
fn add(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
let result = add(5, 3);
println!("Hasil penjumlahan: {}", result);
}
Penjelasan:
- Fungsi
add
memiliki dua parameter,a
danb
, keduanya bertipei32
. - Fungsi ini mengembalikan hasil penjumlahan dari
a
danb
, yang juga bertipei32
.
Nilai Kembalian #
Rust memungkinkan fungsi untuk mengembalikan nilai. Tipe nilai kembalian harus ditentukan setelah panah ->
. Fungsi dapat mengembalikan nilai menggunakan pernyataan return
atau secara implisit mengembalikan nilai dari ekspresi terakhir di dalam fungsi tanpa tanda titik koma (;
).
Contoh Nilai Kembalian:
fn square(x: i32) -> i32 {
x * x
}
fn main() {
let result = square(4);
println!("Hasil kuadrat: {}", result);
}
Penjelasan:
- Fungsi
square
menerima satu parameterx
dan mengembalikan kuadrat darix
. - Nilai
x * x
adalah ekspresi terakhir di dalam fungsi, sehingga secara otomatis dikembalikan tanpa menggunakanreturn
.
Menggunakan return
#
Anda juga bisa menggunakan pernyataan return
untuk mengembalikan nilai lebih awal dari fungsi.
Contoh return
:
fn is_positive(x: i32) -> bool {
if x > 0 {
return true;
}
false
}
fn main() {
let result = is_positive(5);
println!("Apakah positif? {}", result);
}
Penjelasan:
- Fungsi
is_positive
mengembalikantrue
jikax
lebih besar dari 0, ataufalse
sebaliknya. return
digunakan untuk mengembalikan nilai lebih awal ketika kondisi terpenuhi.
Fungsi dengan Tipe Kembalian Unit ()
#
Jika fungsi tidak mengembalikan nilai, tipe kembalian ()
(unit type) biasanya digunakan. Dalam banyak kasus, tipe ()
tidak perlu dituliskan secara eksplisit, karena ini adalah default ketika tidak ada nilai yang dikembalikan.
Contoh Fungsi dengan ()
sebagai Tipe Kembalian:
fn print_message() {
println!("Hello from Rust!");
}
fn main() {
print_message();
}
Penjelasan:
- Fungsi
print_message
tidak mengembalikan nilai, jadi tipe kembalian secara implisit adalah()
.
Fungsi Anonim dan Closure #
Closure adalah fungsi anonim yang bisa menangkap variabel dari lingkup sekitarnya. Closure sangat berguna untuk kasus di mana Anda perlu meneruskan fungsi sebagai argumen atau menyimpan fungsi di dalam variabel.
Sintaks Closure:
let closure_name = |parameter1, parameter2| -> TipeKembalian {
// Blok kode
};
Contoh Closure:
fn main() {
let add = |a, b| a + b;
let result = add(5, 3);
println!("Hasil closure: {}", result);
}
Penjelasan:
add
adalah closure yang menerima dua parametera
danb
dan mengembalikan hasil penjumlahan mereka.- Closure dapat langsung digunakan dengan cara yang sama seperti fungsi biasa.
Closure dengan Capture Environment #
Closure dapat menangkap variabel dari lingkup sekitarnya (environment capture), yang membuatnya berbeda dari fungsi biasa.
Contoh Closure dengan Capture:
fn main() {
let x = 4;
let square = |y| y * x;
let result = square(5);
println!("Hasil closure dengan capture: {}", result);
}
Penjelasan:
- Closure
square
menangkap variabelx
dari lingkup sekitarnya dan menggunakannya di dalam perhitungan.
Fungsi Generik #
Rust mendukung fungsi generik, yang memungkinkan Anda untuk menulis fungsi yang dapat bekerja dengan berbagai tipe data. Tipe generik ditandai dengan tanda kurung sudut <>
di sebelah nama fungsi.
Sintaks Fungsi Generik:
fn function_name<T>(parameter: T) -> T {
// Blok kode
}
Contoh Fungsi Generik:
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list {
if item > largest {
largest = item;
}
}
largest
}
fn main() {
let numbers = vec![34, 50, 25, 100, 65];
let result = largest(&numbers);
println!("Nilai terbesar adalah {}", result);
}
Penjelasan:
T
adalah parameter tipe generik yang digunakan di seluruh fungsilargest
.PartialOrd
adalah trait yang memastikan bahwa tipeT
dapat dibandingkan.
Fungsi dengan Referensi dan Borrowing #
Rust memiliki konsep ownership dan borrowing yang mempengaruhi bagaimana data diakses dalam fungsi. Anda bisa meneruskan referensi (&T
) ke fungsi untuk meminjam data tanpa mengambil alih kepemilikannya.
Contoh Fungsi dengan Referensi:
fn print_length(s: &String) {
println!("Panjang string: {}", s.len());
}
fn main() {
let my_string = String::from("Hello, Rust!");
print_length(&my_string);
}
Penjelasan:
- Fungsi
print_length
menerima referensi keString
, sehingga tidak mengambil alih kepemilikan data. - Di dalam
main
,my_string
masih valid setelah dipinjam olehprint_length
.
Fungsi dengan Mutable References #
Jika Anda perlu mengubah data yang dipinjam, Anda harus menggunakan referensi yang mutable (&mut T
).
Contoh Fungsi dengan Mutable Reference:
fn add_suffix(s: &mut String) {
s.push_str(" - Rust");
}
fn main() {
let mut my_string = String::from("Hello");
add_suffix(&mut my_string);
println!("{}", my_string);
}
Penjelasan:
- Fungsi
add_suffix
menerima referensi mutable keString
dan menambahkan suffix ke string tersebut. - Di dalam
main
,my_string
diubah olehadd_suffix
.
Fungsi sebagai Argumen dan Nilai Kembali #
Rust mendukung penggunaan fungsi sebagai argumen ke fungsi lain dan sebagai nilai kembali dari suatu fungsi.
Contoh Fungsi sebagai Argumen:
fn apply_to_3(f: fn(i32) -> i32) -> i32 {
f(3)
}
fn double(x: i32) -> i32 {
x * 2
}
fn main() {
let result = apply_to_3(double);
println!("Hasil: {}", result);
}
Penjelasan:
- Fungsi
apply_to_3
menerima fungsi lain sebagai argumen dan menerapkannya pada nilai3
. - Di dalam
main
, fungsidouble
diteruskan sebagai argumen keapply_to_3
.
Fungsi Rekursif #
Rust mendukung fungsi rekursif, yaitu fungsi yang memanggil dirinya sendiri. Fungsi rekursif sering digunakan dalam algoritma seperti pencarian, traversal, atau per
hitungan rekursif.
Contoh Fungsi Rekursif:
fn factorial(n: u32) -> u32 {
if n == 0 {
1
} else {
n * factorial(n - 1)
}
}
fn main() {
let result = factorial(5);
println!("Hasil faktorial: {}", result);
}
Penjelasan:
- Fungsi
factorial
memanggil dirinya sendiri untuk menghitung faktorial darin
.
Dokumentasi Fungsi dengan Komentar #
Rust mendorong praktik terbaik dalam dokumentasi dengan menggunakan komentar dokumentasi (///
) yang dapat menghasilkan dokumentasi otomatis.
Contoh Dokumentasi Fungsi:
/// Menghitung penjumlahan dua bilangan bulat.
///
/// # Arguments
///
/// * `a` - Bilangan bulat pertama.
/// * `b` - Bilangan bulat kedua.
///
/// # Returns
///
/// Nilai penjumlahan dari `a` dan `b`.
fn add(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
let result = add(10, 20);
println!("Hasil: {}", result);
}
Penjelasan:
- Komentar dokumentasi digunakan untuk menjelaskan tujuan fungsi, parameter, dan nilai kembalian.
Kesimpulan #
Fungsi di Rust adalah komponen penting yang memungkinkan Anda untuk mengorganisasi kode secara modular dan efektif. Dengan dukungan untuk parameter, nilai kembalian, referensi, closure, fungsi generik, dan banyak lagi, Rust menyediakan alat yang kuat untuk menulis kode yang bersih, efisien, dan aman. Memahami dan memanfaatkan fitur-fitur ini akan membantu Anda menulis program Rust yang lebih baik dan lebih mudah dipelihara.