~/saidqb cat ecosystem/programming-language/rust.md
Rs
Rust
Systems language, memory-safe tanpa garbage collector
commit by saidqb
Intro
Rust: bahasa systems programming, cepat seperti C/C++ tapi memory-safe tanpa garbage collector — dijamin lewat ownership & borrowing yang dicek saat compile time, bukan runtime.
Get Started
bash
# install via rustup
rustup update
rustc --version && cargo --version
cargo new my_project # bikin project baru + git init
cd my_project
cargo run # compile + jalankanSyntax
rust
fn main() {
let name = "SaidQB";
println!("Halo, {name}!");
}- Setiap program butuh fungsi
main()sebagai entry point. - Statement diakhiri
;; block dibungkus{ }. !di belakang nama menandakan macro, misalprintln!.
Output
rust
println!("halo"); // print + newline
print!("tanpa newline");
eprintln!("ke stderr");
let name = "SaidQB";
println!("Halo, {name}!"); // interpolasi langsung
println!("Halo, {}!", name); // positional
println!("{:.2}", 19.999); // format: 2 desimal -> 20.00
let s = format!("{name} - {}", 8); // format! -> hasilnya StringComments
rust
// komentar satu baris
/* komentar
banyak baris */
/// doc comment untuk item di bawahnya (dipakai `cargo doc`)
//! doc comment untuk module/file itu sendiriVariables
rust
let name = "SaidQB"; // immutable by default
let mut age = 8; // mutable, wajib pakai `mut` biar bisa diubah
age += 1;
let age = "delapan"; // shadowing: bikin binding baru, boleh beda tipeData Types
rust
let i: i32 = -8; // signed integer (i8..i128, isize)
let u: u32 = 8; // unsigned integer (u8..u128, usize)
let f: f64 = 19.99; // float (f32, f64)
let b: bool = true;
let c: char = 'R'; // 1 karakter unicode, pakai kutip satu
let t: (i32, f64, char) = (8, 19.99, 'R'); // tuple
let a: [i32; 3] = [1, 2, 3]; // arrayConstants
rust
const MAX_POINTS: u32 = 100_000; // wajib deklarasi tipe, wajib UPPER_SNAKE_CASE
const PI: f64 = 3.14159;
// beda dari `let`: const selalu immutable dan nilainya harus diketahui saat compile timeOperators
rust
5 + 3; 5 - 3; 5 * 3; 5 / 3; 5 % 3; // aritmatika
5 == 5; 5 != 3; 5 > 3; 5 <= 3; // perbandingan
true && false; true || false; !true; // logika
let mut x = 5; x += 1; x *= 2; // compound assignmentBooleans
rust
let active: bool = true;
let is_adult = 8 >= 18; // hasil comparison langsung bool
if active {
println!("aktif");
}If..Else
rust
let age = 18;
if age >= 18 {
println!("dewasa");
} else if age >= 13 {
println!("remaja");
} else {
println!("anak-anak");
}
let status = if age >= 18 { "dewasa" } else { "belum" }; // if sebagai expressionMatch
rust
let number = 3;
match number {
1 => println!("satu"),
2 | 3 => println!("dua atau tiga"), // banyak pattern
4..=6 => println!("empat sampai enam"), // range
_ => println!("lainnya"), // wajib ada, exhaustive check
}
let desc = match number {
n if n < 0 => "negatif", // match guard
0 => "nol",
_ => "positif",
};Loops
rust
let mut i = 0;
let result = loop {
i += 1;
if i == 10 {
break i * 2; // loop bisa `break` dengan nilai balik
}
};While Loops
rust
let mut i = 0;
while i < 5 {
println!("{i}");
i += 1;
}For Loops
rust
for i in 0..5 { println!("{i}"); } // 0..5 eksklusif
for i in 0..=5 { println!("{i}"); } // 0..=5 inklusif
let tags = ["rust", "go", "php"];
for tag in tags.iter() { println!("{tag}"); }
for (i, tag) in tags.iter().enumerate() { println!("{i}: {tag}"); }Functions
rust
fn greet(name: &str) -> String {
format!("Halo, {name}!") // tanpa `;` -> jadi return value (expression)
}
fn divide(a: f64, b: f64) -> Result<f64, String> {
if b == 0.0 {
return Err("division by zero".to_string()); // early return pakai `return`
}
Ok(a / b)
}Scope
rust
fn outer() {
let x = 5; // x hidup selama scope outer()
{
let y = 10; // y hanya hidup di dalam block ini
println!("{x} {y}");
}
// y sudah keluar dari scope di sini, tidak bisa dipakai lagi
}Strings
rust
let s1: &str = "halo"; // string slice, immutable, biasanya literal
let mut s2: String = String::from("halo"); // owned, growable, heap-allocated
s2.push_str(" dunia");
s2.push('!');
s2.len(); s2.to_uppercase(); s2.trim();
s2.split(',').collect::<Vec<&str>>();
let combined = format!("{s1} {s2}");Ownership
rust
let s1 = String::from("halo");
let s2 = s1; // s1 "pindah" (moved) ke s2, s1 tidak bisa dipakai lagi
// println!("{s1}"); // error: value borrowed after move
let s3 = s2.clone(); // clone kalau memang butuh duplikat data asli
fn take_ownership(s: String) { println!("{s}"); } // s dipindah ke dalam fungsi
take_ownership(s3); // s3 tidak bisa dipakai lagi setelah iniBorrowing
rust
fn print_len(s: &String) -> usize { s.len() } // borrow (&), tidak ambil ownership
let s = String::from("halo");
let len = print_len(&s); // s masih bisa dipakai setelah ini
fn append(s: &mut String) { s.push_str("!"); } // mutable borrow
let mut s = String::from("halo");
append(&mut s);
// aturan: boleh banyak &T (immutable borrow) sekaligus, tapi cuma satu &mut T dalam satu waktuData Structures
Rust punya beberapa collection bawaan, dipilih sesuai kebutuhan:
- Array — ukuran fix, dicek saat compile time.
- Vector — mirip array tapi bisa tumbuh (heap-allocated).
- Tuple — kumpulan nilai beda tipe, ukuran fix.
- HashMap — key-value pairs.
- Struct — data custom dengan field bernama.
- Enum — tipe dengan beberapa varian yang mungkin.
Arrays
rust
let arr: [i32; 3] = [1, 2, 3]; // ukuran fix, tidak bisa nambah/kurang
let zeros = [0; 5]; // [0, 0, 0, 0, 0]
arr[0]; arr.len();Vectors
rust
let mut v: Vec<i32> = vec![1, 2, 3];
v.push(4);
v.pop();
v[0]; v.len();
v.iter().sum::<i32>();
let doubled: Vec<i32> = v.iter().map(|x| x * 2).collect();Tuples
rust
let point: (i32, i32, &str) = (10, 20, "A");
point.0; point.1; point.2; // akses via index
let (x, y, label) = point; // destructuringHashMap
rust
use std::collections::HashMap;
let mut scores: HashMap<String, i32> = HashMap::new();
scores.insert(String::from("SaidQB"), 90);
scores.entry(String::from("Guest")).or_insert(0); // insert kalau belum ada
if let Some(score) = scores.get("SaidQB") {
println!("{score}");
}
for (name, score) in &scores { println!("{name}: {score}"); }Structs
rust
struct User {
name: String,
email: String,
active: bool,
}
impl User {
fn new(name: &str, email: &str) -> Self {
User { name: name.to_string(), email: email.to_string(), active: true }
}
fn greet(&self) -> String { format!("Halo, {}", self.name) }
}
let user = User::new("SaidQB", "said@example.com");
println!("{}", user.greet());Enums
rust
enum Status {
Active,
Inactive,
Banned(String), // variant dengan data
}
let status = Status::Banned("spam".to_string());
match status {
Status::Active => println!("aktif"),
Status::Inactive => println!("nonaktif"),
Status::Banned(reason) => println!("banned: {reason}"),
}