Rust: 2026'da Deneyimli Geliştiriciler İçin Temel Kavramlar

Mevcut programlama bilgisiyle Rust'ı hızlıca öğrenmek mümkün. Sahiplik, ödünç alma, yaşam süreleri ve temel kalıplar; C++, Java veya Python'dan gelen geliştiriciler için açıklandı.

Deneyimli Geliştiriciler İçin Rust Rehberi

Rust, yıldan yıla popülerliğini artırmaya devam ediyor ve bunun sağlam nedenleri var: derleme zamanında garanti edilen bellek güvenliği, C++ seviyesinde performans ve modern bir ekosistem. C++, Java veya Python geçmişine sahip deneyimli geliştiriciler için Rust başlangıçta alışılmadık gelebilir, ancak temel kavramlar bir kez anlaşıldığında hızla sezgisel hale gelir.

Neden 2026'da Rust?

Rust, Stack Overflow'da art arda 8 yıl boyunca en sevilen dil olma unvanını korudu. Microsoft, Google, Amazon ve Meta tarafından kritik bileşenler için benimsenen bu dil, çöp toplayıcı olmadan bellek güvenliği sağlar.

Rust Geliştirme Ortamının Kurulumu

Kod yazmadan önce, resmi sürüm yönetim aracı olan rustup aracılığıyla Rust kurulmalıdır.

bash
# install.sh
# Install Rust via rustup (macOS, Linux)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Verify installation
rustc --version
cargo --version

Cargo, Rust'ın paket yöneticisi ve derleme aracıdır. npm, Maven ve Make işlevlerini tek bir tutarlı araçta birleştirir.

bash
# project-setup.sh
# Create a new project
cargo new my_project
cd my_project

# Generated structure:
# my_project/
# ├── Cargo.toml    # Manifest (like package.json)
# └── src/
#     └── main.rs   # Entry point

# Essential commands
cargo build          # Compile the project
cargo run            # Compile and run
cargo test           # Run tests
cargo check          # Check without building (faster)

Değişkenler ve Varsayılan Değişmezlik

Rust, alışılagelen kuralı tersine çevirir: değişkenler varsayılan olarak değişmezdir (immutable). Bu yaklaşım, değişkenliği açıkça düşünmeye zorlar ve birçok hatanın önüne geçer.

variables.rsrust
fn main() {
    // Immutable by default
    let x = 5;
    // x = 6;  // Compile error!

    // Explicitly mutable variable
    let mut y = 5;
    y = 6;  // OK

    // Shadowing: redeclaration in the same scope
    let x = x + 1;  // Creates a new variable x
    let x = x * 2;  // x is now 12

    // Shadowing also allows changing the type
    let spaces = "   ";         // &str
    let spaces = spaces.len();  // usize
}
Gölgeleme (Shadowing) ve Değişkenlik (Mutability)

Gölgeleme yeni bir değişken oluşturur; mut ise mevcut değeri değiştirir. Gölgeleme, değeri dönüştürürken aynı anlamlı ismi korumaya olanak tanır.

Temel Veri Türleri

Rust, mükemmel tür çıkarımına sahip statik tipli bir dildir. Bilinmesi gereken temel ilkel türler aşağıda listelenmiştir.

types.rsrust
fn main() {
    // Signed integers: i8, i16, i32, i64, i128, isize
    let age: i32 = 30;

    // Unsigned integers: u8, u16, u32, u64, u128, usize
    let count: u64 = 1_000_000;  // Underscores for readability

    // Floats: f32, f64 (default)
    let pi: f64 = 3.14159;

    // Boolean
    let active: bool = true;

    // Unicode character (4 bytes)
    let emoji: char = '🦀';

    // Tuple: fixed collection of different types
    let person: (String, i32) = (String::from("Alice"), 28);
    let (name, age) = person;  // Destructuring

    // Array: fixed size, same type
    let numbers: [i32; 5] = [1, 2, 3, 4, 5];
    let first = numbers[0];

    // Slice: view into a portion of data
    let slice: &[i32] = &numbers[1..4];  // [2, 3, 4]
}

Sahiplik (Ownership): Devrimci Kavram

Sahiplik, Rust'ın en büyük yeniliğidir. Bu sistem, çöp toplayıcı olmadan bellek güvenliğini garanti eder; bunun bedeli ise başlangıçtaki öğrenme eğrisidir.

Sahipliğin Üç Kuralı

ownership.rsrust
fn main() {
    // Rule 1: Each value has a single owner
    let s1 = String::from("hello");

    // Rule 2: When the owner goes out of scope, the value is freed
    {
        let s2 = String::from("world");
        // s2 is valid here
    }
    // s2 is dropped, no longer accessible

    // Rule 3: Only one ownership at a time (move)
    let s3 = s1;  // s1 is MOVED to s3
    // println!("{}", s1);  // Error: s1 is no longer valid!
    println!("{}", s3);     // OK: s3 is the owner
}

Taşıma (Move) ve Klonlama (Clone)

move_clone.rsrust
fn main() {
    // Simple types (stack): automatic Copy
    let x = 5;
    let y = x;  // Copy, not move
    println!("x = {}, y = {}", x, y);  // Both are valid

    // Complex types (heap): Move by default
    let s1 = String::from("hello");
    let s2 = s1;  // Move
    // s1 is no longer usable

    // Explicit clone to duplicate
    let s3 = String::from("world");
    let s4 = s3.clone();  // Deep copy
    println!("s3 = {}, s4 = {}", s3, s4);  // Both valid
}
Taşıma ve Fonksiyonlar

Bir değeri fonksiyona geçirmek sahipliği aktarır. Fonksiyon yeni sahip olur ve değer, geri döndürülmedikçe çağrıdan sonra artık erişilemez.

ownership_functions.rsrust
fn main() {
    let s = String::from("hello");
    takes_ownership(s);
    // println!("{}", s);  // Error: s has been moved

    let x = 5;
    makes_copy(x);
    println!("{}", x);  // OK: i32 implements Copy

    // To regain ownership, return the value
    let s2 = String::from("hello");
    let s3 = takes_and_gives_back(s2);
    println!("{}", s3);  // OK
}

fn takes_ownership(s: String) {
    println!("{}", s);
}  // s is dropped here

fn makes_copy(x: i32) {
    println!("{}", x);
}

fn takes_and_gives_back(s: String) -> String {
    s  // Returns ownership
}

Ödünç Alma (Borrowing): Aktarmasız Referanslar

Ödünç alma, bir değeri sahipliğini almadan kullanmayı sağlar. Rust'ta en sık kullanılan mekanizmadır.

borrowing.rsrust
fn main() {
    let s1 = String::from("hello");

    // Immutable reference: read-only
    let len = calculate_length(&s1);
    println!("Length of '{}': {}", s1, len);  // s1 still valid

    // Mutable reference: modification allowed
    let mut s2 = String::from("hello");
    change(&mut s2);
    println!("{}", s2);  // "hello, world"
}

fn calculate_length(s: &String) -> usize {
    s.len()
}  // s goes out of scope but doesn't drop (it's a reference)

fn change(s: &mut String) {
    s.push_str(", world");
}

Ödünç Alma Kuralları

borrowing_rules.rsrust
fn main() {
    let mut s = String::from("hello");

    // Rule 1: Multiple immutable references simultaneously OK
    let r1 = &s;
    let r2 = &s;
    println!("{} and {}", r1, r2);

    // Rule 2: ONLY ONE mutable reference at a time
    let r3 = &mut s;
    // let r4 = &mut s;  // Error: already borrowed mutably
    println!("{}", r3);

    // Rule 3: No mutable ref if immutable ref exists
    let r5 = &s;
    // let r6 = &mut s;  // Error: r5 is still active
    println!("{}", r5);

    // Once r5 is used for the last time, mutable borrow is allowed
    let r7 = &mut s;  // OK: r5 is no longer used after this
    r7.push_str("!");
}

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üreleri (Lifetimes): Referans Geçerliliğinin Güvencesi

Yaşam süreleri, referansların geçerli kalmasını sağlar. Derleyici çoğu zaman bunları otomatik olarak çıkarır, ancak bazen açık belirtim gereklidir.

lifetimes_basic.rsrust
// Classic error: reference to freed data
// fn dangling() -> &String {
//     let s = String::from("hello");
//     &s  // Error: s will be dropped, invalid reference!
// }

// Solution: return the owned value
fn no_dangle() -> String {
    let s = String::from("hello");
    s  // Ownership transferred, no problem
}

Yaşam Süresi Belirtimleri

lifetimes_annotation.rsrust
// The compiler can't figure out which reference will be returned
// fn longest(x: &str, y: &str) -> &str { ... }  // Error!

// Explicit annotation: return lives as long as BOTH x AND y
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("long string");
    let result;
    {
        let string2 = String::from("xyz");
        result = longest(&string1, &string2);
        println!("Longest: {}", result);  // OK here
    }
    // println!("{}", result);  // Error: string2 dropped
}
Yaşam Süresi Elision Kuralları

Rust, basit durumlarda belirtim yapmayı gereksiz kılan elision kuralları uygular. Başlangıç aşamasında, derleyicinin açık hata mesajlarını takip etmek yeterlidir.

Yapılar (Structs) ve Uygulamalar (Implementations)

Yapılar, Rust'ta özel türler oluşturmanın temel yapı taşlarıdır.

structs.rsrust
// Struct definition
#[derive(Debug)]  // Enables printing with {:?}
struct User {
    username: String,
    email: String,
    active: bool,
    sign_in_count: u64,
}

// Implementation block for methods
impl User {
    // Constructor (convention: fn new or descriptive name)
    fn new(username: String, email: String) -> Self {
        Self {
            username,
            email,
            active: true,
            sign_in_count: 1,
        }
    }

    // Method: takes &self (reference to instance)
    fn is_active(&self) -> bool {
        self.active
    }

    // Method with mutation: takes &mut self
    fn deactivate(&mut self) {
        self.active = false;
    }

    // Method consuming self (rare)
    fn into_username(self) -> String {
        self.username
    }
}

fn main() {
    let mut user = User::new(
        String::from("alice"),
        String::from("alice@example.com"),
    );

    println!("Active: {}", user.is_active());
    user.deactivate();
    println!("Active: {}", user.is_active());

    // Debug print
    println!("{:?}", user);
}

Enum'lar ve Desen Eşleştirme (Pattern Matching)

Rust enum'ları, çoğu dildeki enum'lardan çok daha güçlüdür: her varyant veri içerebilir.

enums.rsrust
// Simple enum
enum Direction {
    North,
    South,
    East,
    West,
}

// Enum with data (algebraic data type)
enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(u8, u8, u8),
}

impl Message {
    fn process(&self) {
        match self {
            Message::Quit => println!("Quitting"),
            Message::Move { x, y } => println!("Moving to ({}, {})", x, y),
            Message::Write(text) => println!("Writing: {}", text),
            Message::ChangeColor(r, g, b) => {
                println!("Color: rgb({}, {}, {})", r, g, b)
            }
        }
    }
}

fn main() {
    let msg = Message::Move { x: 10, y: 20 };
    msg.process();

    let msg2 = Message::Write(String::from("Hello Rust!"));
    msg2.process();
}

Option ve Result: Hata Yönetimi Temelleri

option_result.rsrust
use std::fs::File;
use std::io::{self, Read};

fn main() {
    // Option<T>: present or absent value (replaces null)
    let numbers = vec![1, 2, 3];
    let first: Option<&i32> = numbers.first();

    match first {
        Some(n) => println!("First: {}", n),
        None => println!("Empty list"),
    }

    // Utility methods
    let value = first.unwrap_or(&0);
    let doubled = first.map(|n| n * 2);

    // Result<T, E>: success or error
    let result = read_file("config.txt");
    match result {
        Ok(content) => println!("Content: {}", content),
        Err(e) => println!("Error: {}", e),
    }
}

fn read_file(path: &str) -> Result<String, io::Error> {
    let mut file = File::open(path)?;  // ? propagates the error
    let mut content = String::new();
    file.read_to_string(&mut content)?;
    Ok(content)
}
? Operatörü

? operatörü, hata yayılımı için sözdizimsel kolaylıktır. Result Err ise hatayı otomatik olarak döndürür, aksi takdirde Ok değerini açar.

Trait'ler: Rust Tarzı Çok Biçimlilik (Polimorfizm)

Trait'ler, paylaşılan davranışları tanımlar; Java arayüzlerine veya Swift protokollerine benzer.

traits.rsrust
// Trait definition
trait Summary {
    fn summarize(&self) -> String;

    // Method with default implementation
    fn preview(&self) -> String {
        format!("{}...", &self.summarize()[..50.min(self.summarize().len())])
    }
}

struct Article {
    title: String,
    author: String,
    content: String,
}

struct Tweet {
    username: String,
    content: String,
}

// Implementation for Article
impl Summary for Article {
    fn summarize(&self) -> String {
        format!("{} by {}", self.title, self.author)
    }
}

// Implementation for Tweet
impl Summary for Tweet {
    fn summarize(&self) -> String {
        format!("@{}: {}", self.username, self.content)
    }
}

// Function accepting any type implementing Summary
fn notify(item: &impl Summary) {
    println!("Breaking news: {}", item.summarize());
}

// Equivalent syntax with trait bound
fn notify_generic<T: Summary>(item: &T) {
    println!("Breaking news: {}", item.summarize());
}

fn main() {
    let article = Article {
        title: String::from("Rust 2026"),
        author: String::from("Community"),
        content: String::from("..."),
    };

    let tweet = Tweet {
        username: String::from("rustlang"),
        content: String::from("Rust is awesome!"),
    };

    notify(&article);
    notify(&tweet);
}

Temel Koleksiyonlar

Rust standart kütüphanesi güçlü koleksiyon türleri sunar.

collections.rsrust
use std::collections::HashMap;

fn main() {
    // Vec<T>: dynamic array
    let mut numbers: Vec<i32> = Vec::new();
    numbers.push(1);
    numbers.push(2);
    numbers.push(3);

    // vec! macro for initialization
    let nums = vec![1, 2, 3, 4, 5];

    // Iteration
    for n in &nums {
        println!("{}", n);
    }

    // Functional methods
    let doubled: Vec<i32> = nums.iter().map(|x| x * 2).collect();
    let sum: i32 = nums.iter().sum();
    let evens: Vec<&i32> = nums.iter().filter(|x| *x % 2 == 0).collect();

    // String: growable UTF-8 string
    let mut s = String::from("Hello");
    s.push_str(", World!");
    s.push('!');

    // Concatenation
    let s1 = String::from("Hello, ");
    let s2 = String::from("World!");
    let s3 = s1 + &s2;  // s1 moved, s2 borrowed
    // or with format!
    let s4 = format!("{}{}", "Hello, ", "World!");

    // HashMap<K, V>
    let mut scores: HashMap<String, i32> = HashMap::new();
    scores.insert(String::from("Blue"), 10);
    scores.insert(String::from("Red"), 50);

    // Access with get (returns Option)
    if let Some(score) = scores.get("Blue") {
        println!("Blue: {}", score);
    }

    // Entry API for conditional insertion
    scores.entry(String::from("Yellow")).or_insert(25);
}

Rust'ta İdiomatik Hata Yönetimi

Doğru hata yönetimi Rust'ta kritik önem taşır. Önerilen kalıplar aşağıda açıklanmıştır.

error_handling.rsrust
use std::fs::File;
use std::io::{self, Read};
use std::num::ParseIntError;

// Define a custom error type
#[derive(Debug)]
enum AppError {
    Io(io::Error),
    Parse(ParseIntError),
    Custom(String),
}

// Implement From for automatic conversion
impl From<io::Error> for AppError {
    fn from(err: io::Error) -> Self {
        AppError::Io(err)
    }
}

impl From<ParseIntError> for AppError {
    fn from(err: ParseIntError) -> Self {
        AppError::Parse(err)
    }
}

// Function returning Result with custom error
fn read_number_from_file(path: &str) -> Result<i32, AppError> {
    let mut file = File::open(path)?;  // io::Error -> AppError
    let mut content = String::new();
    file.read_to_string(&mut content)?;
    let number: i32 = content.trim().parse()?;  // ParseIntError -> AppError
    Ok(number)
}

fn main() {
    match read_number_from_file("number.txt") {
        Ok(n) => println!("Number: {}", n),
        Err(AppError::Io(e)) => println!("IO error: {}", e),
        Err(AppError::Parse(e)) => println!("Parse error: {}", e),
        Err(AppError::Custom(msg)) => println!("Error: {}", msg),
    }
}
Önerilen Crate'ler

Gerçek projelerde, thiserror crate'i (kütüphaneler için) ve anyhow (uygulamalar için) hata yönetimini büyük ölçüde basitleştirir.

Rust'ta Test Yazımı

Rust, test çerçevesini doğrudan dilin içine entegre eder.

lib.rsrust
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

pub fn divide(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
        Err(String::from("Division by zero"))
    } else {
        Ok(a / b)
    }
}

// Test module (compiled only for `cargo test`)
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_add() {
        assert_eq!(add(2, 3), 5);
    }

    #[test]
    fn test_add_negative() {
        assert_eq!(add(-1, 1), 0);
    }

    #[test]
    fn test_divide_success() {
        assert_eq!(divide(10, 2), Ok(5));
    }

    #[test]
    fn test_divide_by_zero() {
        assert!(divide(10, 0).is_err());
    }

    #[test]
    #[should_panic(expected = "index out of bounds")]
    fn test_panic() {
        let v = vec![1, 2, 3];
        let _ = v[99];  // Panic!
    }
}

Sonuç

Rust, bellek güvenliği ile performansı bir arada sunan benzersiz bir paradigma ortaya koyar. Sahiplik ve ödünç alma kavramları başlangıçta kısıtlayıcı hissedilse de pratikle doğal hale gelir. Rust derleyicisi paha biçilmez bir müttefiktir: hata mesajları sektördeki en iyi örnekler arasında yer alır.

Başlangıç Kontrol Listesi

  • rustup ile Rust kurulumu ve Cargo'ya hakimiyet
  • Değişmezlik ile açık değişkenlik arasındaki farkın kavranması
  • Sahipliğin üç kuralının özümsenmesi
  • & ve &mut referanslarıyla ödünç alma pratiği
  • Null ve istisnalar yerine Option ve Result kullanımı
  • #[test] ile test yazımı

Pratik yapmaya başla!

Mülakat simülatörleri ve teknik testlerle bilgini test et.

Rust topluluğu sıcak ve kaynaklar bolca mevcuttur. Resmi "The Rust Programming Language" kitabı çevrimiçi olarak ücretsiz sunulmaktadır. Bu sağlam temellerle, async/await, makrolar ve WebAssembly gibi ileri konulara geçiş yapmak mümkündür.

Etiketler

#rust
#systems programming
#ownership
#memory safety
#performance

Paylaş

İlgili makaleler