Rust Yaşam Süreleri: Anotasyonlar, Elizyon ve 2026 Mülakat Soruları
Rust yaşam süreleri (lifetimes) hakkında kapsamlı rehber. Anotasyon sözdizimi, elizyon kuralları, struct kalıpları ve 2026 mülakat soruları.

Rust yaşam süreleri, derleyicinin referansların ne kadar süre geçerli kaldığını izlemek için kullandığı mekanizmadır. Bellek yönetiminin çalışma zamanında gerçekleştiği garbage collection kullanan dillerden farklı olarak, Rust'ın borrow checker'ı referans geçerliliğini derleme zamanında doğrular ve kod çalıştırılmadan önce tüm bellek hata kategorilerini ortadan kaldırır.
Rust'ta yaşam süresi, bir referansın geçerli olduğu kapsamı tanımlayan derleme zamanı yapısıdır. Borrow checker, referansların asla işaret ettikleri verileri outlive etmemesini sağlamak için yaşam sürelerini kullanır ve çalışma zamanı yükü olmadan dangling pointer'ları önler.
Yaşam Sürelerinin Bellekte Gerçekte Neyi Temsil Ettiği
Yaşam süreleri, değerlerin ne kadar süre var olduğuyla ilgili değildir. Değerlere yapılan referansların ne kadar süre geçerli kaldığını tanımlarlar. Rust'taki her referansın, anotasyonlar atlanmış olsa bile bir yaşam süresi vardır.
Derleyicinin reddettiği bu fonksiyonu ele alalım:
fn create_dangling() -> &String {
let s = String::from("hello");
&s // HATA: `s` fonksiyonun sonunda drop edilir
}s String'i yalnızca fonksiyon kapsamında yaşar. Ona bir referans döndürmek, fonksiyon döndüğünde String'in belleği serbest bırakıldığı için dangling pointer oluştururdu. Borrow checker bunu derleme zamanında yakalar.
Düzeltme, ya sahiplenilmiş bir değer döndürmeyi ya da referans alınan verinin fonksiyon çağrısını outlive etmesini sağlamayı gerektirir:
// Seçenek 1: Sahiplenilmiş değer döndür
fn create_owned() -> String {
String::from("hello")
}
// Seçenek 2: Fonksiyonu outlive eden veriye referans
fn first_word(s: &str) -> &str {
s.split_whitespace().next().unwrap_or("")
}first_word fonksiyonunda, döndürülen &str girdi s'den ödünç alır, bu yüzden s geçerli olduğu sürece geçerli kalır. Çağıran, girdinin yaşam süresini kontrol eder.
Yaşam Süresi Anotasyon Sözdizimi ve Semantiği
Açık yaşam süresi anotasyonları 'a, 'b ve benzeri sözdizimini kullanır. Bunlar, derleyiciye referansların ne kadar süre yaşaması gerektiğine dair talimatlar değildir. Birden fazla referansın yaşam süreleri arasındaki ilişkileri tanımlarlar.
// Her iki girdi ve çıktı aynı 'a yaşam süresini paylaşır
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
fn main() {
let string1 = String::from("uzun string");
let result;
{
let string2 = String::from("kısa");
result = longest(&string1, &string2);
println!("En uzun: {}", result); // Geçerli: her iki string de canlı
}
// println!("{}", result); // HATA: string2 drop edildi
}'a anotasyonu derleyiciye şunu söyler: döndürülen referans, x ve y'nin yaşam sürelerinin kesişimi boyunca geçerli olacaktır. string2 daha kısa bir yaşam süresine sahip olduğundan, result string2 drop edildikten sonra kullanılamaz.
Birden fazla farklı yaşam süresi, daha karmaşık ilişkileri ifade eder:
// Çıktı yalnızca ilk parametrenin yaşam süresine bağlı
fn first_only<'a, 'b>(x: &'a str, _y: &'b str) -> &'a str {
x
}
fn main() {
let owned = String::from("sahiplenilmiş");
let result;
{
let temporary = String::from("geçici");
result = first_only(&owned, &temporary);
}
// result hala geçerli: yalnızca owned'a bağlı
println!("{}", result);
}Rust 2024'te Yaşam Süresi Elizyon Kuralları
Derleyici, anotasyonlar atlandığında yaşam sürelerini çıkarmak için üç elizyon kuralı uygular. Bu kurallar, güvenlikten ödün vermeden boilerplate'i azaltır.
- Her girdi referansı kendi yaşam süresi parametresini alır
- Tam olarak bir girdi yaşam süresi varsa, tüm çıktı referanslarına uygulanır
&selfveya&mut selfvarsa, onun yaşam süresi tüm çıktı referanslarına uygulanır
Bu kurallar çoğu yaygın kalıbı ele alır:
// Kural 1: Her girdi kendi yaşam süresini alır
fn takes_two(x: &str, y: &str) {}
// Derleyici şöyle okur: fn takes_two<'a, 'b>(x: &'a str, y: &'b str) {}
// Kural 2: Tek girdi yaşam süresi çıktıya yayılır
fn first_char(s: &str) -> &str {
&s[0..1]
}
// Derleyici şöyle okur: fn first_char<'a>(s: &'a str) -> &'a str
// Kural 3: &self yaşam süresi çıktıya yayılır
impl Parser {
fn peek(&self) -> &Token {
&self.tokens[self.position]
}
// Derleyici şöyle okur: fn peek<'a>(&'a self) -> &'a Token
}Elizyon başarısız olduğunda, derleyici açık anotasyonlar gerektirir. Bu en sık, birden fazla girdiden türetilen referansları döndüren fonksiyonlarda olur:
// HATA: Çıktı yaşam süresi belirlenemiyor
fn ambiguous(x: &str, y: &str) -> &str {
if x.len() > y.len() { x } else { y }
}
// DÜZELTME: Açık anotasyon belirsizliği çözer
fn unambiguous<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}Struct Yaşam Süreleri ve Outlives İlişkisi
Referans içeren struct'lar, ödünç alınan verinin struct'ı outlive etmesi gerektiğini ifade etmek için yaşam süresi anotasyonları gerektirir:
struct Excerpt<'a> {
text: &'a str,
}
impl<'a> Excerpt<'a> {
// new girdiden ödünç alır, bu yüzden Excerpt kaynağı outlive edemez
fn new(source: &'a str, start: usize, end: usize) -> Self {
Excerpt { text: &source[start..end] }
}
// level() sahiplenilmiş veri döndürür, imzada yaşam süresi yok
fn level(&self) -> u32 {
self.text.len() as u32 / 10
}
}
fn main() {
let novel = String::from("Bana Ishmael deyin. Birkaç yıl önce...");
let excerpt = Excerpt::new(&novel, 0, 16);
println!("Alıntı: {}", excerpt.text);
} // novel drop edildi, ama excerpt zaten kapsam dışındaExcerpt<'a>'daki 'a, struct'ın geçerliliğini ödünç alınan text'in yaşam süresine bağlar. Kaynak String drop edildikten sonra bir Excerpt kullanmaya çalışmak derleme hatası tetikler.
Birden fazla referansa sahip struct'lar için, her birinin farklı yaşam süreleri olabilir:
struct Comparison<'a, 'b> {
baseline: &'a str,
candidate: &'b str,
}
impl<'a, 'b> Comparison<'a, 'b> {
fn new(baseline: &'a str, candidate: &'b str) -> Self {
Comparison { baseline, candidate }
}
fn baseline_only(&self) -> &'a str {
self.baseline
}
}Rust mülakatlarında başarılı olmaya hazır mısın?
İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.
'static Yaşam Süresi ve Ne Zaman Kullanılmalı
'static yaşam süresi, tüm program yürütmesi boyunca yaşayan veriyi belirtir. String literal'leri binary'ye gömüldükleri için bu yaşam süresine sahiptir:
let s: &'static str = "Sonsuza kadar yaşarım";
// Sabitler örtük olarak 'static'tir
const CONFIG_VERSION: &str = "2.0.0";
// Thread-safe global'ler 'static gerektirir
static COUNTER: AtomicU64 = AtomicU64::new(0);Yaygın bir kalıp, geliştiricileri sıklıkla karıştıran T: 'static bound'larını içerir. Bu bound, T'nin statik olmayan referanslar içermediği anlamına gelir, T'nin bir referans olması gerektiği değil:
use std::thread;
fn spawn_task<T: Send + 'static>(data: T) {
thread::spawn(move || {
// data thread'e taşındı, bağımsız yaşamalı
println!("Thread'de işleniyor");
});
}
fn main() {
let owned = String::from("sahiplenilmiş veri");
spawn_task(owned); // OK: String 'static (kendi verisine sahip)
let reference = "ödünç alınmış";
// spawn_task(reference); // OK: &'static str
}Thread, spawn eden fonksiyonu outlive edebilir, bu yüzden thread'lere taşınan veri stack-local değişkenlere referans içeremez.
Yaygın Yaşam Süresi Hataları ve Çözümleri
Birkaç kalıp, geliştiricileri tutarlı bir şekilde zorlar. Bunları anlamak, hata ayıklamayı hızlandırır.
Yerel değişkenlere referans döndürme:
fn bad_split(text: &str, delimiter: char) -> (&str, &str) {
let parts: Vec<&str> = text.split(delimiter).collect();
(parts[0], parts[1]) // OK: parts[i] text'ten ödünç alır, Vec'ten değil
}
fn truly_bad() -> &str {
let local = String::from("yerel");
&local // HATA: local fonksiyonun sonunda drop edilir
}Uyumsuz yaşam sürelerine sahip struct'larda referans depolama:
struct Cache {
data: String,
// view: &str, // HATA: yaşam süresi parametresi gerekli
}
// Self-referential struct'lar unsafe veya ouroboros gibi crate'ler gerektirir
struct CacheWithView<'a> {
data: String,
view: Option<&'a str>, // self.data'ya güvenli şekilde işaret edemez
}Bir alanın başka bir alana referans verdiği self-referential struct'lar, ya unsafe kod ile Pin ya da ouroboros gibi crate'ler gerektirir.
Trait implementasyonlarında yaşam süresi bound'ları:
trait Processor {
fn process<'a>(&self, input: &'a str) -> &'a str;
}
struct Prefixer {
prefix: String,
}
impl Processor for Prefixer {
// &format!(...) döndürülemez - geçici olurdu
fn process<'a>(&self, input: &'a str) -> &'a str {
input // input veya onun bir parçasını döndürmeli
}
}Genel Yaşam Süreleri İçin Higher-Ranked Trait Bounds (HRTBs)
Higher-ranked trait bounds, bir tipin herhangi bir yaşam süresi için bir trait'i karşılaması gerektiğini ifade etmek için for<'a> sözdizimini kullanır:
use std::fmt::Debug;
// F herhangi bir 'a yaşam süresi ile çağrılabilir olmalı
fn apply_to_refs<F>(f: F)
where
F: for<'a> Fn(&'a str) -> &'a str,
{
let owned = String::from("test");
let result = f(&owned);
println!("{}", result);
}
fn identity(s: &str) -> &str { s }
fn main() {
apply_to_refs(identity);
}HRTB'ler, closure kabul eden API'lerde ve async kalıplarda sıkça görülür.
2026 Yaşam Süresi Mülakat Soruları
Rust mülakatları düzenli olarak yaşam süresi anlayışını test eder, çünkü bunlar doğrudan dilin bellek güvenliği garantileriyle ilişkilidir.
Soru 1: 'static normal bir yaşam süresi anotasyonundan nasıl farklıdır?
'static, verinin tüm program yürütmesi boyunca yaşadığını garanti eder. String literal'leri yürütülebilir binary'ye derlendiği için 'static'tir. T: 'static bound'u, tipin statik olmayan referanslar içermemesini gerektirir, bu threading API'lerinde yaygındır çünkü veri potansiyel olarak spawner'ları outlive etmelidir. Buna karşılık, 'a gibi normal yaşam süreleri kapsam-bağlıdır ve derleyici tarafından kullanıma göre belirlenir.
Soru 2: Rust'taki üç yaşam süresi elizyon kuralı nelerdir?
İlk kural, her girdi referansına farklı yaşam süresi parametreleri atar. İkinci kural, tam olarak bir girdi yaşam süresi varsa, onu tüm çıktı referanslarına uygular. Üçüncü kural, &self veya &mut self içeren metotlarda, self'in yaşam süresini tüm çıktılara uygular. Bu kurallar çıktı yaşam sürelerini belirleyemediğinde, derleyici açık anotasyonlar gerektirir.
Soru 3: Self-referential struct'lar Rust'ta neden sorunludur?
Rust, standart yaşam sürelerini kullanarak bir struct alanının aynı struct'taki başka bir alana referans verdiğini ifade edemez. Struct bellekte taşınabilir ve iç pointer'ları geçersiz kılabilir. Çözümler, referanslar yerine indeksler kullanmayı, sahiplenilmiş ve ödünç alınmış veriyi ayırmayı veya unsafe kod ile Pin tiplerini kullanmayı içerir.
Soru 4: Açık yaşam süresi anotasyonları ne zaman gereklidir?
Açık anotasyonlar, derleyici elizyon kurallarını uygulayamadığında gereklidir: birden fazla girdiden türetilen referansları döndüren fonksiyonlar, referans depolayan struct'lar, karmaşık yaşam süresi ilişkilerine sahip trait implementasyonları ve farklı kısıtlamalara sahip birden fazla ilişkili yaşam süresini içeren durumlar.
Soru 5: Yaşam süreleri borrow checker ile nasıl ilişkilidir?
Borrow checker, bellek güvenliğini uygulamak için yaşam sürelerini kullanır. Referansların ne zaman oluşturulduğunu ve ne zaman geçersiz hale geldiğini izler, hiçbir referansın kendi verisini outlive etmemesini sağlar. Yaşam süresi anotasyonları, derleyici bunları otomatik olarak çıkaramadığında programcıların bu ilişkileri açıkça ifade etmelerini sağlar.
Rust mülakatlarında başarılı olmaya hazır mısın?
İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.
Yaşam Sürelerinde Kovaryans ve Kontravaryans
Rust yaşam süreleri, bir yaşam süresinin başka birinin yerine ne zaman geçebileceğini belirleyen varyans kurallarına tabidir. Varyansı anlamak, gelişmiş generik senaryolarda kritiktir.
// &'a T hem 'a hem de T üzerinde kovaryanttır
fn example<'long, 'short>(r: &'long str) -> &'short str
where
'long: 'short, // 'long 'short'u outlive eder
{
r // Daha kısa beklendiğinde daha uzun yaşam süresi döndürebilir
}
// &'a mut T, T üzerinde invarianttır
fn mutable_example<'a>(r: &'a mut Vec<&'a str>) {
// Vec<&'a str> tam olarak 'a ile eşleşmeli
}Kovaryans, daha kısa beklendiğinde daha uzun yaşam süresinin kullanılmasına izin verir, bu mantıklıdır - daha uzun yaşam süresine sahip bir referans, daha kısa bir kapsamda geçerlidir. Mutable invarians, yanlış yaşam süresine sahip referansların yazılmasından kaynaklanan potansiyel güvenlik ihlallerini önler.
Sonuç ve Sonraki Adımlar
Rust yaşam süreleri, derleme zamanı analizi aracılığıyla çalışma zamanı yükü olmadan bellek güvenliği sağlar. Elizyon kuralları çoğu yaygın durumu ele alırken, açık anotasyonlar karmaşık ilişkileri ifade eder. Yaşam sürelerini anlamak, güvenli, verimli kod yazmayı sağlar ve Rust mülakatlarında esastır.
Hatırlanması gereken temel noktalar:
- Yaşam süreleri, değerlerin değil referansların ne kadar süre geçerli olduğunu tanımlar
- Üç elizyon kuralı çoğu fonksiyon imzasını otomatik olarak ele alır
'static, tüm program yürütmesi boyunca geçerlilik anlamına gelir, genellikle threading bound'larında kullanılır- Referans depolayan struct'lar yaşam süresi parametreleri gerektirir
- Self-referential struct'lar özel işlem gerektirir
Yaşam sürelerinde ustalaşmak, Rust'ın ownership sisteminin tam gücünü açar ve güvenlik veya performanstan ödün vermeden karmaşık soyutlamalar oluşturmayı sağlar.
Pratik yapmaya başla!
Mülakat simülatörleri ve teknik testlerle bilgini test et.
Rust kodundaki hatayı bulabilir misin?
Gerçek bir kod parçası, gizli bir hata, günde bir deneme. Denemek için hesap gerekmez.

Yazan:
Anthony Fillion-MailletSharpSkill kurucusu
10 yılı aşkın süredir fullstack geliştirici. SharpSkill’i yönetiyor ve burada yayımlanan her şeyden sorumlu.
27 Ağustos 2026 tarihinde güncellendi
Paylaş
İlgili makaleler

2026'da Rust Öğrenmek için Thinkful vs Bloc: Bootcamp Karşılaştırması ve Kendi Kendine Öğrenme Rehberi
2026 yılında Rust öğrenmek için Thinkful ve Bloc karşılaştırması. Programlama bootcamp'leri, online kurslar ve en iyi Rust öğrenme yolları hakkında kapsamlı analiz.

2026'da Rust ve SQLx: Derleme Zamanı Kontrollü Sorgular ve Mülakat Soruları
Rust'ta SQLx kullanımı hakkında kapsamlı rehber - derleme zamanı sorgu doğrulaması, ORM karşılaştırmaları ve teknik mülakat soruları.

Rust Öğrenme 2026: Bootcamp Karşılaştırması ve Kendi Kendine Çalışma Kaynakları
Rust bootcamp'leri, çevrimiçi kurslar ve ücretsiz eğitim materyallerinin kapsamlı karşılaştırması. 2026'da Rust kariyeri planlayan geliştiriciler için rehber.