Basic Rust
Rust adalah bahasa pemrograman yang cepat, aman, dan tidak memerlukan garbage collector. Cocok untuk CLI, game, atau web server. Gaya penulisannya mirip C++. Yang paling khas dari Rust adalah ownership & borrowing.
Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Setelah selesai, cek versinya:
rustc --version
cargo --version
Cargo adalah package manager dan build tool bawaan Rust.
Hello World
fn main() {
println!("Halo, dunia!");
}
cargo run
Variabel & Mutability
Variabel defaultnya immutable (tidak bisa diubah). Untuk mengubahnya bisa menambahkan mut.
let umur = 20; // tidak bisa diubah
let mut skor = 10; // bisa diubah
skor = 15;
Konstanta pake const, wajib ada tipe datanya, dan nilainya harus diketahui saat kompilasi:
const PI: f64 = 3.14;
const MAX: i32 = 100;
Variabel yang namanya sama boleh ditulis ulang (shadowing):
let x = 5;
let x = x + 1; // x sekarang 6
let x = "x"; // x sekarang string, tipe beda juga boleh
Tipe Data
Scalar (tunggal)
let a: i32 = -50; // integer bertanda 32-bit
let b: u32 = 50; // integer tanpa tanda 32-bit
let c: f64 = 3.14; // float 64-bit
let d: bool = true;
let e: char = 'A'; // unicode char, pakai petik satu
let f: &str = "Budi"; // string slice
Compound (campuran)
let tuple: (i32, f64, u8) = (500, 6.4, 1);
let (x, y, z) = tuple; // destructuring
println!("{}", x);
let array = [1, 2, 3, 4, 5]; // ukuran tetap
let pertama = array[0];
let v = vec![1, 2, 3]; // vector (bisa bertambah)
v.push(4);
Fungsi
fn tambah(a: i32, b: i32) -> i32 {
a + b // tanpa titik koma di akhir = return otomatis
}
fn main() {
let hasil = tambah(3, 4);
println!("Hasil: {}", hasil);
}
Fungsi yang tidak ngembaliin apa-apa (return () / unit):
fn sapa(nama: &str) {
println!("Halo, {}!", nama);
}
Percabangan
if / else
let nilai = 80;
if nilai >= 75 {
println!("Lulus");
} else if nilai >= 55 {
println!("Remedial");
} else {
println!("Tidak lulus");
}
// if sebagai ekspresi
let status = if nilai >= 75 { "lulus" } else { "tidak lulus" };
loop
let mut hitung = 0;
loop {
hitung += 1;
if hitung == 3 {
break;
}
}
// loop dengan label
'luar: for i in 0..3 {
for j in 0..3 {
if i == 1 && j == 1 {
break 'luar;
}
}
}
while
let mut angka = 3;
while angka != 0 {
println!("{}", angka);
angka -= 1;
}
for (iterator)
for i in 1..=5 { // inklusif 5
println!("{}", i);
}
for i in 0..5 { // eksklusif 5
println!("{}", i);
}
let hari = ["Senin", "Selasa"];
for h in hari.iter() {
println!("{}", h);
}
Ownership & Borrowing
Rust tidak menggunakan garbage collector. Penggantinya adalah ownership — setiap data punya satu pemilik, dan ketika pemiliknya keluar dari scope, data otomatis dihapus.
Move (pemindahan kepemilikan)
let s1 = String::from("hello");
let s2 = s1; // pindah ke s2
// println!("{}", s1); // ERROR! s1 tidak valid lagi
Clone (copy isi)
let s1 = String::from("hello");
let s2 = s1.clone(); // s1 dan s2 keduanya valid
Copy (tipe sederhana otomatis dicopy)
Tipe yang ukurannya diketahui di stack (integer, float, bool, char, tuple yang isinya copy) otomatis implement Copy:
let x = 5;
let y = x; // x masih bisa dipake
Borrowing (pinjam pakai &)
Read (&T), Write (&mut T), tidak boleh menggunakan keduanya secara bersamaan.
fn hitung_panjang(s: &String) -> usize {
s.len()
}
let s1 = String::from("hello");
let panjang = hitung_panjang(&s1); // kepemilikan masih ada di s1
// Ubah pakai mutable reference
let mut s = String::from("hello");
ubah(&mut s);
fn ubah(s: &mut String) {
s.push_str(", dunia");
}
Slice
Slice adalah referensi ke bagian dari koleksi, tetapi tidak memiliki kepemilikan:
let s = String::from("hello dunia");
let hello = &s[0..5]; // "hello"
let dunia = &s[6..11]; // "dunia"
let arr = [1, 2, 3, 4, 5];
let potong = &arr[1..3]; // [2, 3]
Struct
Kumpulan data yang bisa berbeda-beda tipe.
struct Orang {
nama: String,
umur: u32,
aktif: bool,
}
let orang1 = Orang {
nama: String::from("Budi"),
umur: 20,
aktif: true,
};
println!("{} berumur {} tahun", orang1.nama, orang1.umur);
// Update struct dengan ..
let orang2 = Orang {
nama: String::from("Ani"),
..orang1 // copy nilai lain dari orang1
};
// Method (fungsi milik struct)
impl Orang {
fn umur_tambah(&mut self) {
self.umur += 1;
}
fn baru(nama: &str) -> Orang {
Orang {
nama: String::from(nama),
umur: 0,
aktif: true,
}
}
}
let mut o = Orang::baru("Cici");
o.umur_tambah();
Tuple Struct & Unit Struct
struct Warna(i32, i32, i32);
let hitam = Warna(0, 0, 0);
struct SelaluSama;
Enum & Pattern Matching
Enum itu tipe yang nilainya satu dari beberapa pilihan.
enum Hari {
Senin,
Selasa,
Rabu,
Kamis,
Jumat,
Sabtu,
Minggu,
}
let hari_ini = Hari::Selasa;
// Enum dengan data
enum Pesan {
Utup(String),
Susul { username: String, isi: String },
Hapus(i32),
}
let pesan = Pesan::Susul {
username: String::from("Budi"),
isi: String::from("Halo!"),
};
Match (pattern matching)
match hari_ini {
Hari::Senin => println!("Awal minggu"),
Hari::Selasa | Hari::Rabu | Hari::Kamis => println!("Tengah minggu"),
Hari::Jumat => println!("Akhir minggu kerja"),
Hari::Sabtu | Hari::Minggu => println!("Akhir pekan"),
}
if let
let some = Some(5);
if let Some(5) = some {
println!("Dapat lima");
}
Option & Result (Error Handling)
Rust tidak mempunyai null atau exception. Gunakan Option dan Result.
Option
enum Option<T> {
Some(T),
None,
}
let ada: Option<i32> = Some(5);
let kosong: Option<i32> = None;
match ada {
Some(x) => println!("Nilai: {}", x),
None => println!("Kosong"),
}
// cara singkat ambil nilai
let x = ada.unwrap_or(0);
Result
use std::fs::File;
let file = File::open("halo.txt");
match file {
Ok(f) => println!("File berhasil dibuka"),
Err(e) => println!("Gagal buka file: {}", e),
}
// operator ? (propagasi error singkat)
use std::io::{self, Read};
fn baca_isi(path: &str) -> Result<String, io::Error> {
let mut file = File::open(path)?; // kalau error, balik ke pemanggil
let mut isi = String::new();
file.read_to_string(&mut isi)?;
Ok(isi)
}
Collections (Kumpulan Data)
Vector
let mut v = Vec::new();
v.push(1);
v.push(2);
let v2 = vec![1, 2, 3];
let ketiga = &v2[2]; // panic kalau indeks tidak ada
let ketiga2 = v2.get(2); // return Option, aman
String
let mut s = String::from("hello");
s.push(' ');
s.push_str("dunia");
let s2 = String::from("foo");
let s3 = s2 + "bar"; // s2 dipindah kepemilikannya
HashMap
use std::collections::HashMap;
let mut skor = HashMap::new();
skor.insert(String::from("Budi"), 10);
skor.insert(String::from("Ani"), 50);
let nilai = skor.get("Budi");
for (k, v) in &skor {
println!("{}: {}", k, v);
}
Trait & Generics
Trait (perilaku yang bisa diimplementasi tipe data)
trait Bicara {
fn ucapkan(&self);
fn sapaan_default(&self) {
println!("..."); // default implementation
}
}
struct Kucing;
struct Anjing;
impl Bicara for Kucing {
fn ucapkan(&self) {
println!("Meow!");
}
}
impl Bicara for Anjing {
fn ucapkan(&self) {
println!("Guk guk!");
}
}
fn biar_bicara<T: Bicara>(hewan: T) { // trait bound
hewan.ucapkan();
}
let kucing = Kucing;
biar_bicara(kucing);
Generics
struct Titik<T> {
x: T,
y: T,
}
let titik_int = Titik { x: 5, y: 10 };
let titik_float = Titik { x: 1.0, y: 4.0 };
fn terbesar<T: std::cmp::PartialOrd>(daftar: &[T]) -> &T {
let mut terbesar = &daftar[0];
for item in daftar {
if item > terbesar {
terbesar = item;
}
}
terbesar
}
Modules & Crates
mod depan;
mod belakang;
fn main() {
depan::fungsi();
belakang::fungsi();
}
File src/depan.rs:
pub fn fungsi() {
println!("Ini dari modul depan");
}
Untuk menggunakan crate dari luar, tambahkan di Cargo.toml:
[dependencies]
rand = "0.8"
Lalu di kode:
use rand::Rng;
let angka = rand::thread_rng().gen_range(1..=100);
Macro
Macro diakhiri dengan !. Bedanya dengan fungsi, macro bisa menangani sejumlah argumen yang variatif dan diekspansi saat kompilasi.
println!("Halo {}!", "dunia");
vec![1, 2, 3];
format!("{} + {}", 1, 2);
Membuat macro sendiri:
macro_rules! sapa {
($nama:expr) => {
println!("Halo, {}!", $nama);
};
}
sapa!("Budi");
Contoh Program Akhir
use std::io;
struct Buku {
judul: String,
penulis: String,
tahun: u32,
}
impl Buku {
fn baru(judul: &str, penulis: &str, tahun: u32) -> Buku {
Buku {
judul: String::from(judul),
penulis: String::from(penulis),
tahun,
}
}
fn info(&self) -> String {
format!("{} oleh {} ({})", self.judul, self.penulis, self.tahun)
}
}
fn main() {
let buku1 = Buku::baru("The Rust Programming Language", "Steve Klabnik", 2018);
let buku2 = Buku::baru("Clean Code", "Robert C. Martin", 2008);
let daftar = vec![buku1, buku2];
for buku in &daftar {
println!("{}", buku.info());
}
println!("Masukkan nama kamu:");
let mut nama = String::new();
io::stdin().read_line(&mut nama).expect("Gagal baca input");
println!("Halo, {}!", nama.trim());
}
Kesimpulan
Rust agak sulit di awal karena ownership, borrowing, dan lifetime, tapi itu justru membuat program lebih aman dan cepat. Pelajari bertahap, mulai dari project kecil, dan jangan takut sama compiler — dia biasanya ngasih tahu errornya dimana.
Selamat coding! 🦀
"Sesungguhnya yang menyebabkan ilmu hilang adalah lupa dan tidak mengulanginya."
Imam Az-Zuhri rahimahullah
Tags:
Referensi:
Catatan Terkait:

Copyright 2026. All rights reserved.