Program Pertama

fn main, macro println!, dan anatomi program Rust pertama.

Daftar isi

Topik ini membahas anatomi program Rust yang paling sederhana: fungsi main sebagai titik masuk, macro println! untuk mencetak teks, serta tahap kompilasi dengan rustc. Pembaca yang menyelesaikan topik ini dapat menulis program Rust mandiri, mengompilasinya menjadi berkas biner, menjalankannya di terminal, dan menjelaskan peran setiap bagiannya.

Anatomi program pertama#

Program Rust terkecil yang dapat dieksekusi terdiri atas satu fungsi bernama main. Fungsi ini adalah titik masuk (entry point) program, yaitu kode yang pertama kali dijalankan ketika berkas biner dieksekusi. Program yang dikompilasi menjadi berkas biner wajib memuat fungsi main, sedangkan pustaka tidak memerlukannya. Simpan program berikut sebagai halo.rs.

rust halo.rs
fn main() {
    println!("Halo, dunia!");
}
text Keluaran
Halo, dunia!

Empat bagian menyusun program di atas:

  • Kata kunci fn mendefinisikan sebuah fungsi baru.
  • Nama main bersifat khusus karena menandai titik masuk, sehingga Rust selalu memulai eksekusi dari fungsi ini.
  • Tanda kurung () setelah nama fungsi menampung daftar parameter, dan fungsi main tidak menerima parameter apa pun.
  • Kurung kurawal {} membatasi badan fungsi, yaitu kumpulan kode yang dijalankan ketika fungsi dipanggil.

Baris di dalam badan fungsi memanggil println! dengan satu argumen berupa string "Halo, dunia!". Tanda seru di akhir nama bukan kesalahan ketik, melainkan penanda bahwa println! adalah macro, bukan fungsi. Argumen teks diapit tanda kutip ganda karena merupakan string literal, dan titik koma di akhir baris menutup pernyataan pemanggilan tersebut. Rust memakai indentasi empat spasi untuk menyelaraskan kode di dalam kurung kurawal, dan alat rustfmt memformat kode secara otomatis dengan gaya yang sama.

Berkas sumber Rust memakai akhiran .rs, dan nama berkas yang terdiri atas beberapa kata ditulis dengan huruf kecil yang dipisah garis bawah, misalnya program_pertama.rs. Gaya penulisan ini lazim disebut snake case. Konvensi ini seragam dengan penamaan variabel dan fungsi, sehingga nama berkas mengikuti pola yang sama dengan item yang dimuatnya.

Mengompilasi dan menjalankan#

Rust adalah bahasa yang dikompilasi secara ahead-of-time: compiler menerjemahkan kode sumber menjadi berkas biner asli terlebih dahulu, lalu berkas biner tersebut dijalankan tanpa perantara apa pun. Compiler resmi Rust bernama rustc. Simpan halo.rs di sebuah direktori kerja, lalu jalankan perintah berikut dari direktori yang sama.

bash
# kompilasi halo.rs menjadi berkas biner bernama halo, lalu jalankan
rustc --edition=2021 halo.rs -o halo && ./halo
text Keluaran
Halo, dunia!

Bendera --edition=2021 memilih edisi bahasa yang digunakan compiler, dan edisi 2021 adalah edisi yang dipakai sepanjang jalur ini. Opsi -o halo menentukan nama berkas biner hasil kompilasi. Setelah perintah berhasil, direktori kerja memuat berkas biner halo yang dieksekusi langsung oleh sistem operasi tanpa mesin virtual atau interpreter. Alur lengkapnya tampak seperti berikut.

halo.rskode sumberrustchaloberkas biner./haloHalo, dunia!teks di terminal
Alur dari kode sumber ke keluaran program

Kompilasi satu berkas seperti di atas cocok untuk latihan singkat. Pada proyek nyata, Cargo menjalankan kedua tahap tersebut dalam satu perintah cargo run, sekaligus mengelola dependensi dan berkas konfigurasi. Perintah rustc tetap berguna ketika sebuah berkas tunggal perlu diuji cepat tanpa struktur proyek.

Menata teks dengan println!#

Macro println! tidak sekadar mencetak teks tetap. Sepasang kurung kurawal {} di dalam string berfungsi sebagai penampung (placeholder) yang diganti nilai dari argumen di belakangnya. Program berikut memakai tiga variasi penulisan sekaligus.

rust sapa.rs
fn main() {
    let nama = "Citra";
    let baris = 24;

    println!("Halo, {}!", nama);
    println!("{} menulis baris ke-{}", nama, baris);
    println!("{nama} sudah menulis {baris} baris");
    println!("literal kurung kurawal: {{ dan }}");
}
text Keluaran
Halo, Citra!
Citra menulis baris ke-24
Citra sudah menulis 24 baris
literal kurung kurawal: { dan }

Penampung {} yang kosong diisi argumen secara berurutan, sehingga {} pertama menerima nama dan {} kedua menerima baris. Sejak Rust 1.58, nama variabel dapat ditulis langsung di dalam kurung kurawal seperti {nama}, dan bentuk ini mengurangi kekeliruan saat argumen banyak. Dua tanda kurung kurawal berpasangan {{ dan }} dicetak sebagai satu karakter kurung kurawal biasa.

Setiap pemanggilan println! diakhiri pergantian baris. Macro print! mencetak tanpa pergantian baris, sedangkan eprintln! mengarahkan keluarannya ke alur error standar. Jumlah penampung yang tidak cocok dengan jumlah argumen merupakan error kompilasi, bukan kejadian saat program berjalan, sehingga kesalahan penulisan teks tertangkap lebih awal. Seluruh keluarga macro pemformatan seperti format!, print!, dan eprintln! memakai aturan yang sama.

Kesalahan umum#

Lupa tanda seru pada println. Penulisan println tanpa ! membuat compiler mencari fungsi biasa bernama println, dan fungsi semacam itu tidak ada. Potongan berikut memperlihatkan error yang muncul.

bash
printf 'fn main() {\n    println("Halo, dunia!");\n}\n' > salah.rs
rustc --edition=2021 salah.rs 2>&1 | sed -n '1,13p'
text Keluaran
error[E0423]: cannot find function `println` in this scope
 --> salah.rs:2:5
  |
2 |     println("Halo, dunia!");
  |     ^^^^^^^ not found in this scope
  |
  = note: a macro named `println` exists in another namespace
help: use `!` to invoke the macro
  |
2 |     println!("Halo, dunia!");
  |            +

error: aborting due to 1 previous error

Error E0423 menyebutkan bahwa macro bernama println tersedia di namespace lain, dan saran perbaikannya adalah menambahkan tanda seru. Perbaikannya memang sesederhana mengikuti saran tersebut.

Menggunakan kutip tunggal untuk teks. Tanda kutip tunggal di Rust membuat karakter char, bukan string, sehingga 'Halo' ditolak karena berisi lebih dari satu karakter. Teks dengan panjang berapa pun ditulis dengan tanda kutip ganda seperti "Halo", sedangkan kutip tunggal dikhususkan untuk satu karakter seperti 'R'. Pembahasan tipe char beserta ukurannya berada pada topik tipe skalar dan majemuk.

Ringkasan#

  • Fungsi main adalah titik masuk program Rust yang dapat dieksekusi, dan badannya dibatasi kurung kurawal.
  • println! adalah macro pencetakan teks yang ditandai tanda seru, dengan penampung {} yang diisi argumen secara berurutan atau dengan nama variabel.
  • rustc --edition=2021 berkas.rs -o nama mengompilasi kode sumber menjadi berkas biner asli yang dijalankan langsung oleh sistem operasi.
  • Kekeliruan jumlah penampung maupun lupa tanda seru merupakan error kompilasi yang tertangkap sebelum program berjalan.

Referensi#