Sepanjang section ini, a dan b hanyalah nama placeholder — umur konkret selalu diisi ulang oleh kompilator di setiap titik pemanggilan. Ada satu pengecualian yang sudah beberapa kali muncul di pesan error kita: static, lifetime bernama yang maknanya tetap di mana pun ia ditulis. Referensi bertipe &'static T dijamin valid selama program berjalan — dari main dimulai sampai proses berakhir. Kedengarannya sederhana, tetapi 'static adalah lifetime yang paling sering disalahpahami pemula: dianggap jimat perbaikan error, dianggap wajib dipakai selamanya, atau dianggap berlaku untuk semua data yang “cukup lama” hidupnya. Chapter ini menegaskan makna aslinya, membuktikan sumber utamanya lewat string literal, lalu menguji ketiga kesalahpahaman tersebut dengan kode nyata.
Referensi yang Dijamin Sepanjang Program #
Makna &'static T harus dibaca sebagai kontrak jaminan, bukan kewajiban pemakaian: data yang ditunjuk dijamin hidup selama program masih berjalan. Sumber paling alami untuk jaminan seperti itu adalah string literal, karena teks literal disimpan langsung di dalam binary program saat kompilasi — bukan dialokasikan di heap saat runtime. Selama berkas program kita dijalankan oleh sistem operasi, teks tersebut ikut termuat di memori; tidak ada scope yang menghapusnya, tidak ada drop yang menunggunya:
fn main() {
let title: &'static str = "Belajar Rust itu menyenangkan";
println!("Judul: {}", title);
}Output yang Dihasilkan:
Judul: Belajar Rust itu menyenangkanMari kita bedah kode di atas:
- Baris 2 (
let title: &'static str = "Belajar Rust itu menyenangkan";): anotasi&'static strmenyatakan pinjamantitledijamin valid sepanjang program. String literal memenuhi jaminan itu karena tempatnya memang abadi seumur proses — teks berada di binary, bukan di heap milik variabel mana pun. - Baris 3 (
println!("Judul: {}", title);): pemakaian biasa; tidak ada yang istimewa di titik ini. Jaminan seumur program tidak menuntut pemakaian seumur program.
Setiap string literal di Rust bertipe &'static str secara bawaan — pada Chapter-Chapter sebelumnya kita menuliskannya cukup sebagai &str, dan keduanya menunjuk tipe yang sama; &str pada literal adalah &'static str yang lifetime-nya tidak dituliskan.
Fungsi yang Mengembalikan &‘static str #
Nilai kembalian &'static str cocok untuk data konfigurasi bawaan, label tetap, atau teks bantuan yang memang tidak pernah berubah sejak dikompilasi. Fungsi berikut mengembalikan sapaan bawaan tanpa membuat alokasi apa pun di runtime:
fn default_greeting() -> &'static str {
"Selamat datang di dunia Rust"
}
fn main() {
let greeting = default_greeting();
println!("Salam: {}", greeting);
}Output yang Dihasilkan:
Salam: Selamat datang di dunia RustMari kita bedah kode di atas:
- Baris 1 (
fn default_greeting() -> &'static str): tanda tangan tidak memuat parameter, sehingga tidak ada sumber pinjaman dari pemanggil. Satu-satunya nilai&stryang bisa dijanjikan tanpa sumber adalah'static— dan fungsi ini memang hanya menyodorkan literal dari binary. - Baris 2 (
"Selamat datang di dunia Rust"): nilai kembalian berupa literal; tidak adaString::from, tidak ada heap, tidak ada data yang di-drop saat fungsi berakhir. - Baris 6 (
let greeting = default_greeting();):greetingberumur'static, bebas dipakai di titik mana pun setelahnya — jaminan yang tidak bisa diberikan oleh pinjaman dari variabel lokal mana pun.
‘static Bukan Jimat Penghapus Error #
Kesalahpahaman pertama lahir langsung dari pesan kompilator: ingat kembali E0106 di Chapter Masalah Referensi Menggantung — salah satu usulan bantuannya adalah menambahkan &'static pada tipe kembalian. Pemula sering menempelkan usulan itu tanpa membaca syaratnya, berharap error hilang. Untuk data yang dibuat di heap saat runtime, resep tersebut pasti gagal. Kode berikut tidak dapat dikompilasi:
fn make_greeting() -> &'static str {
let text = String::from("Selamat datang di dunia Rust");
&text
}
fn main() {
println!("Salam: {}", make_greeting());
}Pesan error kompilator:
error[E0515]: cannot return reference to local variable `text`
--> main.rs:3:5
|
3 | &text
| ^^^^^ returns a reference to data owned by the current function
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0515`.Pesan E0515 menyebut masalah intinya tanpa basa-basi: nilai kembalian adalah reference ke data milik fungsi itu sendiri. Anotasi 'static tidak mengubah fakta tersebut sedikit pun — text tetap String di heap yang akan di-drop begitu make_greeting selesai, sehingga menjanjikan “data ini hidup seumur program” adalah kebohongan yang ditangkap kompilator. Perbaikan yang jujur ada dua arah: kembalikan literal yang memang 'static, atau kembalikan String utuh dan biarkan kepemilikan pindah ke pemanggil. Semangatnya sama dengan pelajaran section Ownership: ganti kontraknya, bukan menodai datanya.
Bentuk kembar kesalahpahaman ini muncul pada parameter: tanda tangan fn show(text: &'static str) adalah kontrak keras yang menolak pinjaman dari variabel lokal — pemanggilan dengan &local_string akan ditolak dengan E0597 bertuliskan argument requires that … is borrowed for 'static. Kita akan bertemu bentuk penolakan itu secara penuh di Chapter Lifetime Bounds.
‘static Sebagai Jaminan Minimal, Bukan Kewajiban Pemakaian #
Kesalahpahaman kedua mengira nilai 'static wajib dipakai selamanya atau terkunci di satu tempat. Kenyataannya 'static adalah batas bawah umur: referensi boleh dipakai sesaat lalu dibuang, dan — inilah sifat pentingnya — referensi 'static selalu bisa dipakai di posisi yang menuntut umur lebih pendek. Fungsi first_longest dari Chapter Anotasi Lifetime di Fungsi menuntut parameter &'a str dengan a diisi irisan umur kedua argumen; literal 'static masuk mulus ke parameter tersebut:
fn first_longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() >= y.len() {
x
} else {
y
}
}
fn main() {
let literal = "Belajar Rust";
let owned = String::from("Rust");
let result = first_longest(literal, owned.as_str());
println!("Teks terpanjang: {}", result);
}Output yang Dihasilkan:
Teks terpanjang: Belajar RustMari kita bedah kode di atas:
- Baris 10 (
let literal = "Belajar Rust";):literalbertipe&'static str— hidup sepanjang program.owneddi baris 11 berumur lebih pendek: sejakletsampai akhirmain. - Baris 13 (
let result = first_longest(literal, owned.as_str());): parameterxmenuntut&'a str; umur'staticmemenuhi tuntutan umur apa pun, sehinggaadiisi irisan yang ditentukan pinjamanowned— rentang hidupnya dimain. Referensi berumur panjang boleh “menyusut” menjadi umur lebih pendek; arah sebaliknya — pinjaman pendek diklaim'static— justru mustahil. - Baris 14 (
println!("Teks terpanjang: {}", result);):resultdipakai singkat. Jaminan seumur program pada literal tidak memaksa pemakaian seumur program pada hasil.
Kesalahpahaman ketiga mengira semua data yang cukup lama hidup otomatis 'static. Tolok ukurnya bukan lamanya variabel, melainkan asal data: String yang dimiliki main sejak awal program tetap tidak bisa dipinjam sebagai &'static str, karena di akhir main data itu tetap di-drop — bukti bahwa umurnya tidak sampai akhir proses. Hanya data yang memang hidup seumur proses — literal, serta nilai static dan const — yang sah menyandang 'static.
Ringkasan #
Lifetime 'static menjanjikan data yang ditunjuk hidup selama program berjalan, dan sumber utamanya adalah string literal yang tersimpan di binary — bukan heap milik variabel. Fungsi tanpa parameter reference hanya boleh mengembalikan &'static str bila nilai kembaliannya memang konstanta seumur proses; menjanjikan 'static atas data heap lokal ditolak sebagai E0515, dan parameter &'static menolak pinjaman lokal dengan E0597. Sebagai jaminan minimal, referensi 'static bebas dipakai singkat dan selalu diterima pada posisi yang menuntut umur lebih pendek. Satu bentuk terakhir menyempurnakan peta kita: menggabungkan lifetime dengan generic — bound T: 'a.