<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://sonsuzus.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://sonsuzus.github.io/" rel="alternate" type="text/html" /><updated>2026-08-03T07:13:51+00:00</updated><id>https://sonsuzus.github.io/feed.xml</id><title type="html">SonsuzUs</title><subtitle>Programlama ve Yazılım</subtitle><author><name>Sonsuz Us</name></author><entry><title type="html">Dinamik Koleksiyonlar ve Vektörler: Heap Üzerinde Esnek Bellek Yönetimi</title><link href="https://sonsuzus.github.io/posts/dinamik-koleksiyonlar-ve-vektorler-heap-uzerinde-esnek-bellek-yonetimi/" rel="alternate" type="text/html" title="Dinamik Koleksiyonlar ve Vektörler: Heap Üzerinde Esnek Bellek Yönetimi" /><published>2026-08-03T00:00:00+00:00</published><updated>2026-08-03T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/dinamik-koleksiyonlar-ve-vektorler-heap-uzerinde-esnek-bellek-yonetimi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/dinamik-koleksiyonlar-ve-vektorler-heap-uzerinde-esnek-bellek-yonetimi/"><![CDATA[<p>Sabit boyutlu bir dizi, kaç misafir geleceğini aylar öncesinden bilerek masa hazırlamaya benzer. Dinamik koleksiyon ise kapı çaldıkça masaya yeni sandalye ekler; gerektiğinde sandalyeleri kaldırır. Vektörler bu esnekliği sunarken arka planda heap belleği, kapasite hesaplarını ve eleman taşıma işlemlerini yönetir.</p>

<p>``</p>

<h2 id="sabit-dizi-ile-dinamik-vektör-arasındaki-fark">Sabit Dizi ile Dinamik Vektör Arasındaki Fark</h2>

<p>Sabit bir dizinin boyutu oluşturulurken belirlenir ve sonradan değiştirilemez. Daha fazla elemana ihtiyaç duyulursa daha büyük bir alan ayırmak, eski elemanları kopyalamak ve önceki alanı serbest bırakmak gerekir. Vektör bütün bu işleri otomatikleştiren bir soyutlamadır.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Sabit boyutlu dizi</th>
      <th>Dinamik vektör</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Boyut</td>
      <td>Başlangıçta belirlenir</td>
      <td>Çalışma zamanında değişir</td>
    </tr>
    <tr>
      <td>Bellek</td>
      <td>Stack veya heap olabilir</td>
      <td>Eleman deposu genellikle heap üzerindedir</td>
    </tr>
    <tr>
      <td>Ekleme</td>
      <td>Boş yer yoksa mümkün değildir</td>
      <td>Kapasite artırılarak yapılabilir</td>
    </tr>
    <tr>
      <td>Yönetim</td>
      <td>Çoğunlukla geliştiriciye aittir</td>
      <td>Koleksiyon sınıfı tarafından gerçekleştirilir</td>
    </tr>
    <tr>
      <td>Erişim</td>
      <td>İndeksle hızlıdır</td>
      <td>İndeksle hızlıdır</td>
    </tr>
  </tbody>
</table>

<p>Vektör nesnesinin kendisi stack üzerinde bulunabilir; ancak elemanların tutulduğu büyük ve bitişik bellek bloğu heap üzerinde ayrılır. Nesne genellikle üç önemli bilgi taşır: veri bloğunun adresi, mevcut eleman sayısı ve ayrılmış toplam kapasite.</p>

<h2 id="boyut-ve-kapasite-aynı-şey-değildir">Boyut ve Kapasite Aynı Şey Değildir</h2>

<p>Vektörün <strong>size</strong> değeri gerçekten kullanılan eleman sayısını, <strong>capacity</strong> değeri ise yeniden bellek ayırmadan saklayabileceği eleman sayısını gösterir. Her eklemede bellek istemek pahalı olacağı için kapasite çoğunlukla ihtiyaçtan büyük tutulur.</p>

\[0 \leq size \leq capacity\]

<p>Kapasite dolduğunda daha büyük bir blok ayrılır. Yaygın büyüme stratejilerinden biri kapasiteyi yaklaşık iki katına çıkarmaktır:</p>

\[C_{yeni} = 2C_{eski}\]

<p>Ardından mevcut elemanlar yeni alana kopyalanır veya taşınır, eski heap bloğu serbest bırakılır ve yeni eleman eklenir. Bu yeniden yerleştirme tek seferde $O(n)$ maliyetli olsa da her eklemede gerçekleşmez. Bu nedenle sona ekleme işleminin amortize edilmiş zaman karmaşıklığı $O(1)$ kabul edilir.</p>

<h2 id="c-ile-vektörü-gözlemlemek">C++ ile Vektörü Gözlemlemek</h2>

<p>Aşağıdaki örnek, eleman eklendikçe boyut ve kapasitenin nasıl değiştiğini gösterir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">sayilar</span><span class="p">;</span>

    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="mi">10</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">sayilar</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">i</span> <span class="o">*</span> <span class="mi">10</span><span class="p">);</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Boyut: "</span> <span class="o">&lt;&lt;</span> <span class="n">sayilar</span><span class="p">.</span><span class="n">size</span><span class="p">()</span>
                  <span class="o">&lt;&lt;</span> <span class="s">", Kapasite: "</span> <span class="o">&lt;&lt;</span> <span class="n">sayilar</span><span class="p">.</span><span class="n">capacity</span><span class="p">()</span>
                  <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">push_back</code>, elemanı sona ekler. Kapasite yeterliyse işlem doğrudan yapılır. Yeterli değilse yeni heap alanı ayrılır ve elemanlar taşınır. Kapasitenin büyüme oranı C++ standardında kesin olarak belirtilmediğinden sonuç kullanılan kütüphane uygulamasına göre değişebilir.</p>

<h2 id="önceden-yer-ayırmak">Önceden Yer Ayırmak</h2>

<p>Kaç eleman ekleneceği yaklaşık olarak biliniyorsa <code class="language-plaintext highlighter-rouge">reserve</code> kullanmak gereksiz yeniden ayırmaları önler:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">puanlar</span><span class="p">;</span>
<span class="n">puanlar</span><span class="p">.</span><span class="n">reserve</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span> <span class="c1">// En az 1000 elemanlık kapasite hazırlar.</span>

<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">1000</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">puanlar</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">reserve</code>, vektörün boyutunu değiştirmez; yalnızca kapasite ayırır. Buna karşılık <code class="language-plaintext highlighter-rouge">resize</code>, eleman sayısını değiştirir ve gerekirse yeni elemanlar oluşturur.</p>

<table>
  <thead>
    <tr>
      <th>İşlem</th>
      <th style="text-align: right">Boyutu değiştirir mi?</th>
      <th style="text-align: right">Kapasiteyi değiştirebilir mi?</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">reserve(n)</code></td>
      <td style="text-align: right">Hayır</td>
      <td style="text-align: right">Evet</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">resize(n)</code></td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Evet</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">clear()</code></td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Genellikle hayır</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">shrink_to_fit()</code></td>
      <td style="text-align: right">Hayır</td>
      <td style="text-align: right">Azaltmayı deneyebilir</td>
    </tr>
  </tbody>
</table>

<h2 id="dikkat-i̇şaretçiler-geçersizleşebilir">Dikkat: İşaretçiler Geçersizleşebilir</h2>

<p>Yeniden bellek ayırma gerçekleştiğinde eski bloğu gösteren işaretçiler, referanslar ve iterator’lar geçersiz hale gelebilir. Artık tahliye edilmiş bir evin adresine kargo göndermek gibi düşünün: adres tanıdık görünür, fakat içeride kimse yoktur.</p>

<p>Vektörler hız, bitişik bellek düzeni ve esneklik arasında güçlü bir denge kurar. Yine de bu rahatlığın arkasında kapasite fazlası, taşıma maliyeti ve referans geçersizleşmesi bulunur. <code class="language-plaintext highlighter-rouge">size</code>, <code class="language-plaintext highlighter-rouge">capacity</code>, <code class="language-plaintext highlighter-rouge">reserve</code> ve yeniden ayırma mantığını bilmek, dinamik koleksiyonları yalnızca kullanmayı değil, verimli ve güvenli kullanmayı sağlar.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="veri yapıları" /><category term="bellek yönetimi" /><category term="C++ vector" /><summary type="html"><![CDATA[Sabit boyutlu bir dizi, kaç misafir geleceğini aylar öncesinden bilerek masa hazırlamaya benzer. Dinamik koleksiyon ise kapı çaldıkça masaya yeni sandalye ekler; gerektiğinde sandalyeleri kaldırır. Vektörler bu esnekliği sunarken arka planda heap belleği, kapasite hesaplarını ve eleman taşıma işlemlerini yönetir.]]></summary></entry><entry><title type="html">Jenerikler ile Tek Kod, Birçok Tip: Esnek ve Tekrarsız Programlama</title><link href="https://sonsuzus.github.io/posts/jenerikler-ile-tek-kod-bircok-tip-esnek-ve-tekrarsiz-programlama/" rel="alternate" type="text/html" title="Jenerikler ile Tek Kod, Birçok Tip: Esnek ve Tekrarsız Programlama" /><published>2026-08-03T00:00:00+00:00</published><updated>2026-08-03T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/jenerikler-ile-tek-kod-bircok-tip-esnek-ve-tekrarsiz-programlama</id><content type="html" xml:base="https://sonsuzus.github.io/posts/jenerikler-ile-tek-kod-bircok-tip-esnek-ve-tekrarsiz-programlama/"><![CDATA[<p>Aynı işlemi <code class="language-plaintext highlighter-rouge">Int</code>, <code class="language-plaintext highlighter-rouge">String</code> ve özel veri tipleri için ayrı ayrı yazdığınızı düşünün. Kod çalışır; fakat proje büyüdükçe kopyalanmış fonksiyonlar küçük bir klon ordusuna dönüşür. Jenerikler (Generics), fonksiyonları, yapıları ve enum’ları belirli bir tipe kilitlemeden tanımlamamızı sağlar. Böylece tip güvenliğinden vazgeçmeden daha esnek, yeniden kullanılabilir ve bakımı kolay kod üretiriz.</p>

<p>``</p>

<h2 id="jeneriklerin-temel-mantığı">Jeneriklerin Temel Mantığı</h2>

<p>Jenerik programlamada somut bir tip yerine <strong>tip parametresi</strong> kullanılır. Genellikle <code class="language-plaintext highlighter-rouge">T</code>, <code class="language-plaintext highlighter-rouge">U</code>, <code class="language-plaintext highlighter-rouge">Element</code> veya <code class="language-plaintext highlighter-rouge">Value</code> gibi isimlerle gösterilen bu parametre, kod kullanılırken gerçek bir tipe dönüşür.</p>

<p>Örneğin iki değerin yerini değiştiren işlemi her veri tipi için ayrı yazmak gereksizdir. Swift ile jenerik sürümü şöyle tanımlanabilir:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="n">yerDegistir</span><span class="o">&lt;</span><span class="kt">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">_</span> <span class="nv">ilk</span><span class="p">:</span> <span class="k">inout</span> <span class="kt">T</span><span class="p">,</span> <span class="n">_</span> <span class="nv">ikinci</span><span class="p">:</span> <span class="k">inout</span> <span class="kt">T</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">gecici</span> <span class="o">=</span> <span class="n">ilk</span>
    <span class="n">ilk</span> <span class="o">=</span> <span class="n">ikinci</span>
    <span class="n">ikinci</span> <span class="o">=</span> <span class="n">gecici</span>
<span class="p">}</span>

<span class="k">var</span> <span class="nv">x</span> <span class="o">=</span> <span class="mi">10</span>
<span class="k">var</span> <span class="nv">y</span> <span class="o">=</span> <span class="mi">20</span>
<span class="nf">yerDegistir</span><span class="p">(</span><span class="o">&amp;</span><span class="n">x</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">y</span><span class="p">)</span>

<span class="k">var</span> <span class="nv">ad1</span> <span class="o">=</span> <span class="s">"Ada"</span>
<span class="k">var</span> <span class="nv">ad2</span> <span class="o">=</span> <span class="s">"Linus"</span>
<span class="nf">yerDegistir</span><span class="p">(</span><span class="o">&amp;</span><span class="n">ad1</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">ad2</span><span class="p">)</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">T</code>, çağrı sırasında Swift tarafından belirlenir. İlk çağrıda <code class="language-plaintext highlighter-rouge">Int</code>, ikinci çağrıda <code class="language-plaintext highlighter-rouge">String</code> olur. Fonksiyonun gövdesi ise yalnızca bir kez yazılmıştır.</p>

<p>Kod tekrarının yaklaşık maliyetini $C_{tekrar} = n \times m$ şeklinde düşünebiliriz. Burada $n$ desteklenen tip sayısı, $m$ ise her uygulamanın bakım maliyetidir. Jenerik yaklaşımda bu maliyet ideal olarak $C_{jenerik} \approx m$ seviyesine iner.</p>

<h2 id="jenerik-ve-geleneksel-yaklaşım">Jenerik ve Geleneksel Yaklaşım</h2>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Tipe Özel Kod</th>
      <th>Jenerik Kod</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kod tekrarı</td>
      <td>Yüksek</td>
      <td>Düşük</td>
    </tr>
    <tr>
      <td>Tip güvenliği</td>
      <td>Var</td>
      <td>Var</td>
    </tr>
    <tr>
      <td>Yeniden kullanım</td>
      <td>Sınırlı</td>
      <td>Yüksek</td>
    </tr>
    <tr>
      <td>Bakım kolaylığı</td>
      <td>Tip sayısıyla azalır</td>
      <td>Merkezi yapı sayesinde artar</td>
    </tr>
    <tr>
      <td>İlk okuma kolaylığı</td>
      <td>Daha basit</td>
      <td>Biraz soyutlama bilgisi ister</td>
    </tr>
  </tbody>
</table>

<p>Jenerikler, <code class="language-plaintext highlighter-rouge">Any</code> kullanmakla aynı şey değildir. <code class="language-plaintext highlighter-rouge">Any</code>, farklı tipleri kabul ederken tip hakkındaki bilgiyi büyük ölçüde çalışma zamanına bırakır. Jenerikler ise derleme zamanında gerçek tipi korur. Bu nedenle yanlış tip kullanımları program çalışmadan yakalanabilir.</p>

<h2 id="jenerik-yapılar">Jenerik Yapılar</h2>

<p>Bir yığın veri yapısı yalnızca sayılarla çalışmak zorunda değildir. Kitaplar, kullanıcılar veya uzay gemileri de aynı yığına eklenebilir; tabii aynı örnek içinde eleman tipi tutarlı olmak şartıyla.</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">Yigin</span><span class="o">&lt;</span><span class="kt">Element</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="kd">private</span> <span class="k">var</span> <span class="nv">elemanlar</span><span class="p">:</span> <span class="p">[</span><span class="kt">Element</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="k">mutating</span> <span class="kd">func</span> <span class="nf">ekle</span><span class="p">(</span><span class="n">_</span> <span class="nv">eleman</span><span class="p">:</span> <span class="kt">Element</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">elemanlar</span><span class="o">.</span><span class="nf">append</span><span class="p">(</span><span class="n">eleman</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="k">mutating</span> <span class="kd">func</span> <span class="nf">cikar</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">Element</span><span class="p">?</span> <span class="p">{</span>
        <span class="n">elemanlar</span><span class="o">.</span><span class="nf">popLast</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">var</span> <span class="nv">sayilar</span> <span class="o">=</span> <span class="kt">Yigin</span><span class="o">&lt;</span><span class="kt">Int</span><span class="o">&gt;</span><span class="p">()</span>
<span class="n">sayilar</span><span class="o">.</span><span class="nf">ekle</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span>
<span class="n">sayilar</span><span class="o">.</span><span class="nf">ekle</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span>

<span class="k">var</span> <span class="nv">diller</span> <span class="o">=</span> <span class="kt">Yigin</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;</span><span class="p">()</span>
<span class="n">diller</span><span class="o">.</span><span class="nf">ekle</span><span class="p">(</span><span class="s">"Swift"</span><span class="p">)</span>
<span class="n">diller</span><span class="o">.</span><span class="nf">ekle</span><span class="p">(</span><span class="s">"Rust"</span><span class="p">)</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">Element</code>, yığının saklayacağı tipi temsil eder. Aynı yapı tanımıyla sınırsız sayıda tip için güvenli yığınlar oluşturulabilir.</p>

<h2 id="enumlarda-jenerik-gücü">Enum’larda Jenerik Gücü</h2>

<p>Ağ işlemlerinde başarı durumunda veri, başarısızlık durumunda hata taşımak yaygın bir ihtiyaçtır. Jenerik enum bu iki değerin tipini dışarıdan alabilir:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">enum</span> <span class="kt">APIResult</span><span class="o">&lt;</span><span class="kt">Success</span><span class="p">,</span> <span class="kt">Failure</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">case</span> <span class="nf">success</span><span class="p">(</span><span class="kt">Success</span><span class="p">)</span>
    <span class="k">case</span> <span class="nf">failure</span><span class="p">(</span><span class="kt">Failure</span><span class="p">)</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">User</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">id</span><span class="p">:</span> <span class="kt">Int</span>
    <span class="k">let</span> <span class="nv">name</span><span class="p">:</span> <span class="kt">String</span>
<span class="p">}</span>

<span class="kd">enum</span> <span class="kt">NetworkError</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">timeout</span>
    <span class="k">case</span> <span class="n">unauthorized</span>
<span class="p">}</span>

<span class="k">let</span> <span class="nv">result</span><span class="p">:</span> <span class="kt">APIResult</span><span class="o">&lt;</span><span class="kt">User</span><span class="p">,</span> <span class="kt">NetworkError</span><span class="o">&gt;</span> <span class="o">=</span>
    <span class="o">.</span><span class="nf">success</span><span class="p">(</span><span class="kt">User</span><span class="p">(</span><span class="nv">id</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nv">name</span><span class="p">:</span> <span class="s">"Grace"</span><span class="p">))</span>
</code></pre></div></div>

<p>Bu model, başarılı sonucun <code class="language-plaintext highlighter-rouge">User</code>, hatanın ise <code class="language-plaintext highlighter-rouge">NetworkError</code> olduğunu açıkça belirtir. Böylece belirsiz sözlükler veya zorunlu tip dönüşümleri ortadan kalkar.</p>

<h2 id="tip-kısıtlamaları">Tip Kısıtlamaları</h2>

<p>Her jenerik işlem bütün tiplerle çalışamaz. Örneğin iki değerin eşitliğini kontrol etmek için tipin <code class="language-plaintext highlighter-rouge">Equatable</code> protokolüne uyması gerekir:</p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">func</span> <span class="n">ayniMi</span><span class="o">&lt;</span><span class="kt">T</span><span class="p">:</span> <span class="kt">Equatable</span><span class="o">&gt;</span><span class="p">(</span><span class="n">_</span> <span class="nv">sol</span><span class="p">:</span> <span class="kt">T</span><span class="p">,</span> <span class="n">_</span> <span class="nv">sag</span><span class="p">:</span> <span class="kt">T</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Bool</span> <span class="p">{</span>
    <span class="n">sol</span> <span class="o">==</span> <span class="n">sag</span>
<span class="p">}</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">ayniMi</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">))</span>
<span class="nf">print</span><span class="p">(</span><span class="nf">ayniMi</span><span class="p">(</span><span class="s">"Swift"</span><span class="p">,</span> <span class="s">"Kotlin"</span><span class="p">))</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">T: Equatable</code> ifadesi, “Herhangi bir tip olabilir ama eşitlik karşılaştırmasını desteklemeli” demektir. Kısıtlamalar jenerikleri daraltmaz; aksine hangi yeteneklere güvenilebileceğini açıkça tanımlar.</p>

<p>Jenerikler doğru kullanıldığında kod tabanını küçültür, hataları derleme aşamasına taşır ve soyutlamaları güçlendirir. Ancak yalnızca bir yerde kullanılacak basit kodu gereksiz yere jenerikleştirmek okunabilirliği azaltabilir. Altın kural şudur: Aynı davranış birden fazla tip için gerçekten anlamlıysa jenerikler sahneye çıkmalı; aksi hâlde soyutlama pelerinini dolapta bırakmalıdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="generics" /><category term="swift" /><category term="temiz kod" /><summary type="html"><![CDATA[Aynı işlemi Int, String ve özel veri tipleri için ayrı ayrı yazdığınızı düşünün. Kod çalışır; fakat proje büyüdükçe kopyalanmış fonksiyonlar küçük bir klon ordusuna dönüşür. Jenerikler (Generics), fonksiyonları, yapıları ve enum’ları belirli bir tipe kilitlemeden tanımlamamızı sağlar. Böylece tip güvenliğinden vazgeçmeden daha esnek, yeniden kullanılabilir ve bakımı kolay kod üretiriz.]]></summary></entry><entry><title type="html">Kapanışlar ve İteratörler: Veriyi Fonksiyonel Bir Akışa Dönüştürmek</title><link href="https://sonsuzus.github.io/posts/kapanislar-ve-iteratorler-veriyi-fonksiyonel-bir-akisa-donusturmek/" rel="alternate" type="text/html" title="Kapanışlar ve İteratörler: Veriyi Fonksiyonel Bir Akışa Dönüştürmek" /><published>2026-08-03T00:00:00+00:00</published><updated>2026-08-03T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/kapanislar-ve-iteratorler-veriyi-fonksiyonel-bir-akisa-donusturmek</id><content type="html" xml:base="https://sonsuzus.github.io/posts/kapanislar-ve-iteratorler-veriyi-fonksiyonel-bir-akisa-donusturmek/"><![CDATA[<p>Kapanışlar (closures) ve iteratörler, veriyi “nasıl dolaşacağımızı” adım adım anlatmak yerine “hangi dönüşümleri istediğimizi” ifade etmemizi sağlar. Kapanışlar çevrelerindeki değişkenleri hatırlayan isimsiz fonksiyonlardır; iteratörler ise koleksiyon elemanlarını sırayla üreten soyutlamalardır. Birlikte kullanıldıklarında kısa, okunabilir ve yeniden kullanılabilir veri işleme zincirleri ortaya çıkar.</p>

<p>``</p>

<h2 id="kapanış-neden-sıradan-bir-fonksiyondan-farklıdır">Kapanış neden sıradan bir fonksiyondan farklıdır?</h2>

<p>Normal bir fonksiyon çoğunlukla yalnızca parametrelerine ve erişebildiği genel değerlere bağlıdır. Kapanış ise tanımlandığı kapsamın değişkenlerini <strong>yakalayabilir</strong>. Matematiksel açıdan sıradan bir fonksiyonu</p>

\[f(x)=x^2\]

<p>şeklinde düşünürsek, dışarıdaki $a$ değerini yakalayan kapanış şu aileyi temsil eder:</p>

\[f_a(x)=ax^2\]

<p>Burada $a$, açıkça parametre olarak verilmemesine rağmen hesaplamanın parçasıdır. Kapanışın yanında taşıdığı bu çevresel bilgilere bazen <strong>closure environment</strong> denir.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Normal fonksiyon</th>
      <th>Kapanış</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>İsme ihtiyaç duyar mı?</td>
      <td>Genellikle evet</td>
      <td>Hayır</td>
    </tr>
    <tr>
      <td>Dış değişken yakalar mı?</td>
      <td>Genellikle hayır</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td>Kısa işlemlerde kullanım</td>
      <td>Daha törensel</td>
      <td>Oldukça pratik</td>
    </tr>
    <tr>
      <td>Durum taşıyabilir mi?</td>
      <td>Ek yapı gerekir</td>
      <td>Yakalanan değerlerle taşıyabilir</td>
    </tr>
  </tbody>
</table>

<p>Rust’ta bir kapanış çevresindeki değeri referansla ödünç alabilir, değiştirilebilir biçimde ödünç alabilir veya sahipliğini üstlenebilir. Derleyici buna göre kapanışı <code class="language-plaintext highlighter-rouge">Fn</code>, <code class="language-plaintext highlighter-rouge">FnMut</code> ya da <code class="language-plaintext highlighter-rouge">FnOnce</code> davranışlarından biriyle ilişkilendirir.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">katsayi</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
    <span class="k">let</span> <span class="n">carp</span> <span class="o">=</span> <span class="p">|</span><span class="n">sayi</span><span class="p">:</span> <span class="nb">i32</span><span class="p">|</span> <span class="n">sayi</span> <span class="o">*</span> <span class="n">katsayi</span><span class="p">;</span>

    <span class="nd">println!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span> <span class="nf">carp</span><span class="p">(</span><span class="mi">5</span><span class="p">));</span> <span class="c1">// 15</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">carp</code>, <code class="language-plaintext highlighter-rouge">katsayi</code> değişkenini çevresinden yakalar. Böylece her çağrıda katsayıyı ayrıca göndermemiz gerekmez.</p>

<h2 id="i̇teratör-koleksiyon-değil-üretim-süreci">İteratör: Koleksiyon değil, üretim süreci</h2>

<p>İteratör bir koleksiyonun kendisi değildir; sıradaki elemanın nasıl elde edileceğini tanımlayan bir mekanizmadır. Temel fikir, her adımda ya yeni bir değer ya da akışın bittiğini bildiren sonuç üretmektir.</p>

<p>$n$ elemanlı bir koleksiyon tek kez dolaşılıyorsa zaman karmaşıklığı çoğunlukla</p>

\[T(n)=O(n)\]

<p>olur. <code class="language-plaintext highlighter-rouge">map</code>, <code class="language-plaintext highlighter-rouge">filter</code> ve <code class="language-plaintext highlighter-rouge">take</code> gibi işlemlerin zincirlenmesi mutlaka her aşamada yeni bir koleksiyon oluşturmaz. Birçok dilde, özellikle Rust’ta, iteratörler <strong>tembeldir</strong>: Sonuç tüketilene kadar hesaplama başlamaz.</p>

<table>
  <thead>
    <tr>
      <th>İşlem</th>
      <th>Görevi</th>
      <th>Sonuç türü</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">map</code></td>
      <td>Her elemanı dönüştürür</td>
      <td>Yeni iteratör</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">filter</code></td>
      <td>Koşula uyanları geçirir</td>
      <td>Yeni iteratör</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">take</code></td>
      <td>İlk belirli sayıda değeri alır</td>
      <td>Sınırlı iteratör</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">fold</code></td>
      <td>Değerleri tek sonuçta birleştirir</td>
      <td>Tek değer</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">collect</code></td>
      <td>Akışı koleksiyona dönüştürür</td>
      <td>Koleksiyon</td>
    </tr>
  </tbody>
</table>

<h2 id="i̇kisini-birlikte-kullanalım">İkisini birlikte kullanalım</h2>

<p>Aşağıdaki örnek çift sayıları seçer, dışarıdan yakalanan katsayıyla çarpar ve sonuçları toplar:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">sayilar</span> <span class="o">=</span> <span class="nd">vec!</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">];</span>
    <span class="k">let</span> <span class="n">katsayi</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>

    <span class="k">let</span> <span class="n">toplam</span><span class="p">:</span> <span class="nb">i32</span> <span class="o">=</span> <span class="n">sayilar</span>
        <span class="nf">.iter</span><span class="p">()</span>
        <span class="nf">.filter</span><span class="p">(|</span><span class="n">sayi</span><span class="p">|</span> <span class="o">*</span><span class="n">sayi</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
        <span class="nf">.map</span><span class="p">(|</span><span class="n">sayi</span><span class="p">|</span> <span class="n">sayi</span> <span class="o">*</span> <span class="n">katsayi</span><span class="p">)</span>
        <span class="nf">.sum</span><span class="p">();</span>

    <span class="nd">println!</span><span class="p">(</span><span class="s">"Toplam: {}"</span><span class="p">,</span> <span class="n">toplam</span><span class="p">);</span> <span class="c1">// 120</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">filter</code> içindeki kapanış yalnızca çift değerleri geçirir. <code class="language-plaintext highlighter-rouge">map</code> kapanışı ise <code class="language-plaintext highlighter-rouge">katsayi</code> değişkenini yakalayarak değerleri dönüştürür. <code class="language-plaintext highlighter-rouge">sum</code>, tembel zinciri tüketen <strong>terminal işlem</strong> olduğu için gerçek hesaplama bu noktada gerçekleşir.</p>

<p>Aynı yaklaşım klasik bir döngüyle de yazılabilir; ancak iteratör zinciri “indeksi artır, elemana eriş, sonucu geçici değişkende tut” ayrıntılarını gizler. Böylece kod, mekanizmadan çok niyeti anlatır.</p>

<h2 id="ne-zaman-dikkatli-olmalıyız">Ne zaman dikkatli olmalıyız?</h2>

<p>Uzun ve iç içe kapanış zincirleri okunabilirliği azaltabilir. Yan etkiler, karmaşık hata yönetimi veya çok sayıda koşul varsa işlemleri isimlendirilmiş fonksiyonlara ayırmak daha sağlıklıdır. Ayrıca sahiplik kullanan dillerde <code class="language-plaintext highlighter-rouge">move</code> ile yakalanan bir değerin artık önceki kapsamda kullanılamayabileceği unutulmamalıdır.</p>

<p>Özetle kapanışlar davranışı veri gibi taşır, iteratörler ise veriyi kontrollü bir akışa dönüştürür. Birlikte kullanıldıklarında döngü yazmaktan fazlasını yaparız: Dönüşümleri birbirine bağlayan küçük ve güçlü bir işlem hattı kurarız.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="closures" /><category term="iteratörler" /><category term="fonksiyonel programlama" /><summary type="html"><![CDATA[Kapanışlar (closures) ve iteratörler, veriyi “nasıl dolaşacağımızı” adım adım anlatmak yerine “hangi dönüşümleri istediğimizi” ifade etmemizi sağlar. Kapanışlar çevrelerindeki değişkenleri hatırlayan isimsiz fonksiyonlardır; iteratörler ise koleksiyon elemanlarını sırayla üreten soyutlamalardır. Birlikte kullanıldıklarında kısa, okunabilir ve yeniden kullanılabilir veri işleme zincirleri ortaya çıkar.]]></summary></entry><entry><title type="html">Null Kabusuna Son: Rust Option Enum ile Güvenli Hata Yönetimi</title><link href="https://sonsuzus.github.io/posts/null-kabusuna-son-rust-option-enum-ile-guvenli-hata-yonetimi/" rel="alternate" type="text/html" title="Null Kabusuna Son: Rust Option Enum ile Güvenli Hata Yönetimi" /><published>2026-08-03T00:00:00+00:00</published><updated>2026-08-03T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/null-kabusuna-son-rust-option-enum-ile-guvenli-hata-yonetimi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/null-kabusuna-son-rust-option-enum-ile-guvenli-hata-yonetimi/"><![CDATA[<p>Bir nesnenin var olduğunu düşünerek kod yazarsınız, uygulamayı çalıştırırsınız ve aniden meşhur “null reference” hatasıyla karşılaşırsınız. Rust, bu sürprizi çalışma zamanına bırakmak yerine bir değerin yokluğunu <code class="language-plaintext highlighter-rouge">Option</code> enum’u ile açıkça modellememizi ister. Böylece “Belki vardır, belki yoktur” ihtimali, derleyicinin denetleyebildiği güvenli bir tipe dönüşür.
``</p>
<h2 id="option-neden-gereklidir">Option neden gereklidir?</h2>

<p>Java, C# ve JavaScript gibi dillerde bir referansın <code class="language-plaintext highlighter-rouge">null</code> olması mümkündür. Buna rağmen değişkenin tipi çoğu zaman bu ihtimali yeterince görünür kılmaz. Programcı kontrol yapmayı unutursa hata çalışma zamanında ortaya çıkar.</p>

<p>Rust’ta sıradan bir referans kendiliğinden <code class="language-plaintext highlighter-rouge">null</code> olamaz. Bir değerin bulunmaması geçerli bir durumsa standart kütüphanedeki şu enum kullanılır:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">enum</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="nf">Some</span><span class="p">(</span><span class="n">T</span><span class="p">),</span>
    <span class="nb">None</span><span class="p">,</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">T</code>, saklanabilecek değerin tipidir. Örneğin <code class="language-plaintext highlighter-rouge">Option&lt;i32&gt;</code>, ya <code class="language-plaintext highlighter-rouge">Some(i32)</code> biçiminde bir tam sayı ya da <code class="language-plaintext highlighter-rouge">None</code> içerir. Olası durumların sayısını basitçe şöyle gösterebiliriz:</p>

\[Option(T) = T + 1\]

<p>Formüldeki ekstra bir durum <code class="language-plaintext highlighter-rouge">None</code> seçeneğidir. Örneğin <code class="language-plaintext highlighter-rouge">bool</code> iki farklı değere sahipken <code class="language-plaintext highlighter-rouge">Option&lt;bool&gt;</code> üç durumu temsil eder: <code class="language-plaintext highlighter-rouge">Some(true)</code>, <code class="language-plaintext highlighter-rouge">Some(false)</code> ve <code class="language-plaintext highlighter-rouge">None</code>.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Değer varsa</th>
      <th>Değer yoksa</th>
      <th>Güvenlik</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Null kullanılabilen referans</td>
      <td>Nesne</td>
      <td><code class="language-plaintext highlighter-rouge">null</code></td>
      <td>Kontrol unutulabilir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Option&lt;T&gt;</code></td>
      <td><code class="language-plaintext highlighter-rouge">Some(T)</code></td>
      <td><code class="language-plaintext highlighter-rouge">None</code></td>
      <td>Derleyici iki durumu da ele aldırır</td>
    </tr>
    <tr>
      <td>Varsayılan değer</td>
      <td>Gerçek değer</td>
      <td>Örneğin <code class="language-plaintext highlighter-rouge">0</code></td>
      <td>Yokluk ile gerçek değer karışabilir</td>
    </tr>
  </tbody>
</table>

<h2 id="pattern-matching-ile-değeri-açmak">Pattern matching ile değeri açmak</h2>

<p><code class="language-plaintext highlighter-rouge">Option</code> içindeki veriye doğrudan erişilemez. Önce hangi varyantla karşı karşıya olduğumuzu belirlememiz gerekir. En açık yöntem <code class="language-plaintext highlighter-rouge">match</code> ifadesidir:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">kullanici_bul</span><span class="p">(</span><span class="n">id</span><span class="p">:</span> <span class="nb">u32</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">if</span> <span class="n">id</span> <span class="o">==</span> <span class="mi">42</span> <span class="p">{</span>
        <span class="nf">Some</span><span class="p">(</span><span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"Ada"</span><span class="p">))</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="nb">None</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">match</span> <span class="nf">kullanici_bul</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span> <span class="p">{</span>
        <span class="nf">Some</span><span class="p">(</span><span class="n">isim</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="nd">println!</span><span class="p">(</span><span class="s">"Kullanıcı bulundu: {isim}"</span><span class="p">),</span>
        <span class="nb">None</span> <span class="k">=&gt;</span> <span class="nd">println!</span><span class="p">(</span><span class="s">"Kullanıcı bulunamadı"</span><span class="p">),</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Fonksiyon, sonuç bulmayı garanti etmediği için <code class="language-plaintext highlighter-rouge">String</code> yerine <code class="language-plaintext highlighter-rouge">Option&lt;String&gt;</code> döndürür. <code class="language-plaintext highlighter-rouge">match</code>, hem <code class="language-plaintext highlighter-rouge">Some</code> hem de <code class="language-plaintext highlighter-rouge">None</code> kolunu yazmamızı zorunlu tutar. Bir kol unutulursa program derlenmez; yani hata, kullanıcıya ulaşmadan yakalanır.</p>

<p>Yalnızca değer bulunduğunda işlem yapılacaksa <code class="language-plaintext highlighter-rouge">if let</code> daha kısa olabilir:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">isim</span><span class="p">)</span> <span class="o">=</span> <span class="nf">kullanici_bul</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span> <span class="p">{</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"Hoş geldin, {isim}!"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="option-yardımcı-metotları">Option yardımcı metotları</h2>

<p>Rust, sık kullanılan senaryolar için pratik metotlar sunar:</p>

<table>
  <thead>
    <tr>
      <th>Metot</th>
      <th>Davranış</th>
      <th>Uygun kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">unwrap_or(x)</code></td>
      <td><code class="language-plaintext highlighter-rouge">None</code> ise <code class="language-plaintext highlighter-rouge">x</code> döndürür</td>
      <td>Güvenli varsayılan değer</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">map(f)</code></td>
      <td>Mevcut değeri dönüştürür</td>
      <td>Kısa veri işleme zinciri</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">and_then(f)</code></td>
      <td>Yeni bir <code class="language-plaintext highlighter-rouge">Option</code> üreten işlem yapar</td>
      <td>Ardışık kontroller</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">is_some()</code></td>
      <td>Değer varsa <code class="language-plaintext highlighter-rouge">true</code> döndürür</td>
      <td>Yalnızca varlık kontrolü</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">unwrap()</code></td>
      <td>Değeri çıkarır, yoksa panikletir</td>
      <td>Varlık kesin olarak kanıtlandıysa</td>
    </tr>
  </tbody>
</table>

<p>Örneğin yaş bilgisini güvenli biçimde dönüştürebiliriz:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">yas_metni</span><span class="p">(</span><span class="n">yas</span><span class="p">:</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="nb">u8</span><span class="o">&gt;</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">String</span> <span class="p">{</span>
    <span class="n">yas</span><span class="nf">.map</span><span class="p">(|</span><span class="n">deger</span><span class="p">|</span> <span class="nd">format!</span><span class="p">(</span><span class="s">"{deger} yaşında"</span><span class="p">))</span>
        <span class="nf">.unwrap_or</span><span class="p">(</span><span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"Yaş bilinmiyor"</span><span class="p">))</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">map</code>, yalnızca değer varsa closure’ı çalıştırır. Sonuç <code class="language-plaintext highlighter-rouge">None</code> kalırsa <code class="language-plaintext highlighter-rouge">unwrap_or</code> varsayılan metni üretir. Böylece elle dallanma yazmadan güvenli bir akış kurulur.</p>

<h2 id="option-ile-result-aynı-şey-değildir">Option ile Result aynı şey değildir</h2>

<p><code class="language-plaintext highlighter-rouge">Option</code>, yalnızca değer bulunup bulunmadığını anlatır. Başarısızlığın nedenini de taşımak gerekiyorsa <code class="language-plaintext highlighter-rouge">Result&lt;T, E&gt;</code> daha uygundur.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">bol</span><span class="p">(</span><span class="n">a</span><span class="p">:</span> <span class="nb">f64</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="nb">f64</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">Option</span><span class="o">&lt;</span><span class="nb">f64</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">if</span> <span class="n">b</span> <span class="o">==</span> <span class="mf">0.0</span> <span class="p">{</span> <span class="nb">None</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="nf">Some</span><span class="p">(</span><span class="n">a</span> <span class="o">/</span> <span class="n">b</span><span class="p">)</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu örnekte yokluk sebebi zaten açıktır. Dosya okuma gibi bir işlemde ise “dosya yok”, “izin reddedildi” veya “disk hatası” ayrımı gerektiğinden <code class="language-plaintext highlighter-rouge">Result</code> seçilmelidir.</p>

<p>Kısacası <code class="language-plaintext highlighter-rouge">Option</code>, null değerini sihirli ve tehlikeli bir istisna olmaktan çıkarıp tip sisteminin parçası yapar. Rust size “Bu değer kesinlikle var mı?” sorusunu kod derlenmeden önce sordurur. Biraz disiplin karşılığında daha az gece yarısı hatası alınır; bu da oldukça kârlı bir takastır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Rust" /><category term="Option" /><category term="Hata Yönetimi" /><summary type="html"><![CDATA[Bir nesnenin var olduğunu düşünerek kod yazarsınız, uygulamayı çalıştırırsınız ve aniden meşhur “null reference” hatasıyla karşılaşırsınız. Rust, bu sürprizi çalışma zamanına bırakmak yerine bir değerin yokluğunu Option enum’u ile açıkça modellememizi ister. Böylece “Belki vardır, belki yoktur” ihtimali, derleyicinin denetleyebildiği güvenli bir tipe dönüşür.]]></summary></entry><entry><title type="html">Panik Yok: Rust Result Enum ile Kurtarılabilir Hataları Yönetmek</title><link href="https://sonsuzus.github.io/posts/panik-yok-rust-result-enum-ile-kurtarilabilir-hatalari-yonetmek/" rel="alternate" type="text/html" title="Panik Yok: Rust Result Enum ile Kurtarılabilir Hataları Yönetmek" /><published>2026-08-03T00:00:00+00:00</published><updated>2026-08-03T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/panik-yok-rust-result-enum-ile-kurtarilabilir-hatalari-yonetmek</id><content type="html" xml:base="https://sonsuzus.github.io/posts/panik-yok-rust-result-enum-ile-kurtarilabilir-hatalari-yonetmek/"><![CDATA[<p>Bir dosyanın bulunamaması, kullanıcının harf yerine sayı girmesi veya sunucunun geçici olarak yanıt vermemesi programın kıyamet senaryosu değildir. Bunlar beklenebilen ve çoğu zaman düzeltilebilen durumlardır. Rust, böyle hataları görünmez bir kontrol akışına teslim etmek yerine <code class="language-plaintext highlighter-rouge">Result</code> enum’u aracılığıyla açıkça modellememizi sağlar. Böylece hata yönetimi, kodun kenarında unutulan bir ayrıntı değil, fonksiyonun sözleşmesinin parçası olur.
``</p>
<h2 id="kurtarılabilir-hata-nedir">Kurtarılabilir hata nedir?</h2>

<p>Hataları kabaca iki gruba ayırabiliriz. Programın varsayımlarını tamamen bozan durumlar kurtarılamaz kabul edilir ve Rust’ta çoğunlukla <code class="language-plaintext highlighter-rouge">panic!</code> ile ilişkilendirilir. Eksik dosya, geçersiz kullanıcı girdisi veya başarısız ağ isteği gibi olaylarsa kurtarılabilir hatalardır. Program bunları kullanıcıya bildirebilir, işlemi tekrarlayabilir ya da alternatif bir yol seçebilir.</p>

<p>Bir işlemin sonucunu basitçe şu küme gibi düşünebiliriz:</p>

\[R = \{Ok(T), Err(E)\}\]

<p>Burada $T$ başarılı değerin, $E$ ise hata bilgisinin türüdür. Rust standart kütüphanesindeki yapı kavramsal olarak şöyledir:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">enum</span> <span class="nb">Result</span><span class="o">&lt;</span><span class="n">T</span><span class="p">,</span> <span class="n">E</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="nf">Ok</span><span class="p">(</span><span class="n">T</span><span class="p">),</span>
    <span class="nf">Err</span><span class="p">(</span><span class="n">E</span><span class="p">),</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu tanım, bir fonksiyonun aynı anda hem başarı hem hata olamayacağını anlatır. Sonuç iki olasılıktan tam olarak biridir.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Başarı durumu</th>
      <th>Hata durumu</th>
      <th>Derleyici kontrolü</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">try-catch</code></td>
      <td>Normal dönüş</td>
      <td>Fırlatılan exception</td>
      <td>Genellikle sınırlı</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Result&lt;T, E&gt;</code></td>
      <td><code class="language-plaintext highlighter-rouge">Ok(T)</code></td>
      <td><code class="language-plaintext highlighter-rouge">Err(E)</code></td>
      <td>Güçlü ve açık</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">panic!</code></td>
      <td>Dönüş beklenmez</td>
      <td>Program akışı kesilir</td>
      <td>Kurtarma amacı taşımaz</td>
    </tr>
  </tbody>
</table>

<h2 id="result-değerini-eşleştirmek">Result değerini eşleştirmek</h2>

<p>Bir metni sayıya dönüştüren fonksiyon yazalım. Fonksiyon hata mesajını da dönüş türünde ilan ediyor:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">sayiya_cevir</span><span class="p">(</span><span class="n">girdi</span><span class="p">:</span> <span class="o">&amp;</span><span class="nb">str</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">Result</span><span class="o">&lt;</span><span class="nb">i32</span><span class="p">,</span> <span class="nb">String</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">match</span> <span class="n">girdi</span><span class="nf">.trim</span><span class="p">()</span><span class="py">.parse</span><span class="p">::</span><span class="o">&lt;</span><span class="nb">i32</span><span class="o">&gt;</span><span class="p">()</span> <span class="p">{</span>
        <span class="nf">Ok</span><span class="p">(</span><span class="n">sayi</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="nf">Ok</span><span class="p">(</span><span class="n">sayi</span><span class="p">),</span>
        <span class="nf">Err</span><span class="p">(</span><span class="n">_</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="nf">Err</span><span class="p">(</span><span class="nd">format!</span><span class="p">(</span><span class="s">"Geçersiz sayı: {girdi}"</span><span class="p">)),</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">match</span> <span class="nf">sayiya_cevir</span><span class="p">(</span><span class="s">"42"</span><span class="p">)</span> <span class="p">{</span>
        <span class="nf">Ok</span><span class="p">(</span><span class="n">deger</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="nd">println!</span><span class="p">(</span><span class="s">"Sonuç: {deger}"</span><span class="p">),</span>
        <span class="nf">Err</span><span class="p">(</span><span class="n">hata</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="nd">eprintln!</span><span class="p">(</span><span class="s">"Hata: {hata}"</span><span class="p">),</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">match</code>, iki ihtimali de ele almaya zorlar. Böylece hata yolunu yanlışlıkla unutmak zorlaşır. Üstelik hata bir değer olduğu için kaydedilebilir, dönüştürülebilir veya başka bir fonksiyona aktarılabilir.</p>

<h2 id="soru-işareti-operatörüyle-erken-dönüş">Soru işareti operatörüyle erken dönüş</h2>

<p>Her adımda <code class="language-plaintext highlighter-rouge">match</code> yazmak güvenli olsa da kodu kalabalıklaştırabilir. <code class="language-plaintext highlighter-rouge">?</code> operatörü, değer <code class="language-plaintext highlighter-rouge">Ok</code> ise içeriğini çıkarır; <code class="language-plaintext highlighter-rouge">Err</code> ise hatayı çağıran fonksiyona hemen döndürür.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="n">fs</span><span class="p">;</span>
<span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="n">io</span><span class="p">;</span>

<span class="k">fn</span> <span class="nf">ayarlari_oku</span><span class="p">()</span> <span class="k">-&gt;</span> <span class="nb">Result</span><span class="o">&lt;</span><span class="nb">String</span><span class="p">,</span> <span class="nn">io</span><span class="p">::</span><span class="n">Error</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">icerik</span> <span class="o">=</span> <span class="nn">fs</span><span class="p">::</span><span class="nf">read_to_string</span><span class="p">(</span><span class="s">"ayarlar.txt"</span><span class="p">)</span><span class="o">?</span><span class="p">;</span>
    <span class="nf">Ok</span><span class="p">(</span><span class="n">icerik</span><span class="p">)</span>
<span class="p">}</span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">match</span> <span class="nf">ayarlari_oku</span><span class="p">()</span> <span class="p">{</span>
        <span class="nf">Ok</span><span class="p">(</span><span class="n">ayarlar</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="nd">println!</span><span class="p">(</span><span class="s">"Ayarlar yüklendi:</span><span class="se">\n</span><span class="s">{ayarlar}"</span><span class="p">),</span>
        <span class="nf">Err</span><span class="p">(</span><span class="n">hata</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="nd">eprintln!</span><span class="p">(</span><span class="s">"Ayarlar okunamadı: {hata}"</span><span class="p">),</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu akış matematiksel olarak ardışık işlemlerin başarısına bağlıdır. $A$ ve $B$ adımları için toplam başarı koşulu $A \land B$ olur. İlk <code class="language-plaintext highlighter-rouge">Err</code> oluştuğunda zincir kısa devre yapar; gereksiz işlemler çalışmaz.</p>

<h2 id="result-dönüştürme-araçları">Result dönüştürme araçları</h2>

<p>Rust, sık kullanılan senaryolar için yardımcı metotlar sunar:</p>

<table>
  <thead>
    <tr>
      <th>Metot</th>
      <th>Kullanım amacı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">map</code></td>
      <td>Başarılı değeri dönüştürür</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">map_err</code></td>
      <td>Hata değerini dönüştürür</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">and_then</code></td>
      <td>Yeni bir <code class="language-plaintext highlighter-rouge">Result</code> üreten işlemi zincirler</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">unwrap_or</code></td>
      <td>Hata halinde varsayılan değer verir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">expect</code></td>
      <td>Hata halinde açıklamalı panik oluşturur</td>
    </tr>
  </tbody>
</table>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">iki_kati</span><span class="p">(</span><span class="n">girdi</span><span class="p">:</span> <span class="o">&amp;</span><span class="nb">str</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">Result</span><span class="o">&lt;</span><span class="nb">i32</span><span class="p">,</span> <span class="nb">String</span><span class="o">&gt;</span> <span class="p">{</span>
    <span class="n">girdi</span>
        <span class="py">.parse</span><span class="p">::</span><span class="o">&lt;</span><span class="nb">i32</span><span class="o">&gt;</span><span class="p">()</span>
        <span class="nf">.map</span><span class="p">(|</span><span class="n">sayi</span><span class="p">|</span> <span class="n">sayi</span> <span class="o">*</span> <span class="mi">2</span><span class="p">)</span>
        <span class="nf">.map_err</span><span class="p">(|</span><span class="n">_</span><span class="p">|</span> <span class="s">"Sayı biçimi geçersiz"</span><span class="nf">.to_string</span><span class="p">())</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">map</code>, yalnızca başarı halinde çalışır; <code class="language-plaintext highlighter-rouge">map_err</code> ise yalnızca hatayı uygulamaya uygun bir mesaja çevirir. Bu ayrım, mutlu yol ile hata yolunu birbirine dolamadan yönetir.</p>

<p><code class="language-plaintext highlighter-rouge">unwrap</code> ve <code class="language-plaintext highlighter-rouge">expect</code> hızlı prototiplerde kullanışlıdır ancak üretim kodunda ölçülü kullanılmalıdır; çünkü <code class="language-plaintext highlighter-rouge">Err</code> geldiğinde programı panikletirler. Beklenen hatalarda <code class="language-plaintext highlighter-rouge">match</code>, <code class="language-plaintext highlighter-rouge">?</code> ve dönüştürme metotları daha dayanıklı tercihlerdir. Kısacası <code class="language-plaintext highlighter-rouge">Result</code>, hataları saklamaz: onları görünür, tür güvenli ve test edilebilir verilere dönüştürür. Program da tökezlediğinde yere kapanmak yerine neden tökezlediğini anlayıp yoluna devam eder.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Rust" /><category term="Result Enum" /><category term="Hata Yönetimi" /><summary type="html"><![CDATA[Bir dosyanın bulunamaması, kullanıcının harf yerine sayı girmesi veya sunucunun geçici olarak yanıt vermemesi programın kıyamet senaryosu değildir. Bunlar beklenebilen ve çoğu zaman düzeltilebilen durumlardır. Rust, böyle hataları görünmez bir kontrol akışına teslim etmek yerine Result enum’u aracılığıyla açıkça modellememizi sağlar. Böylece hata yönetimi, kodun kenarında unutulan bir ayrıntı değil, fonksiyonun sözleşmesinin parçası olur.]]></summary></entry><entry><title type="html">Rust HashMap Rehberi: Anahtar-Değer Dünyasında Sahiplik Macerası</title><link href="https://sonsuzus.github.io/posts/rust-hashmap-rehberi-anahtar-deger-dunyasinda-sahiplik-macerasi/" rel="alternate" type="text/html" title="Rust HashMap Rehberi: Anahtar-Değer Dünyasında Sahiplik Macerası" /><published>2026-08-03T00:00:00+00:00</published><updated>2026-08-03T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/rust-hashmap-rehberi-anahtar-deger-dunyasinda-sahiplik-macerasi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/rust-hashmap-rehberi-anahtar-deger-dunyasinda-sahiplik-macerasi/"><![CDATA[<p>Bir telefon rehberinde kişileri sayfa sayfa aramak yerine isimlerini doğrudan yazarak numaralarına ulaştığınızı düşünün. Hash haritaları tam olarak bu fikri programlama dünyasına taşır: Veriler, anahtar ve değer çiftleri hâlinde saklanır. Rust’ın <code class="language-plaintext highlighter-rouge">HashMap</code> koleksiyonu ise bu pratik yapıyı dilin sahiplik, ödünç alma ve yaşam süresi kurallarıyla birleştirerek hem hızlı hem de güvenli veri yönetimi sunar.
``</p>
<h2 id="hash-haritasının-çalışma-mantığı">Hash haritasının çalışma mantığı</h2>

<p>Bir hash haritasındaki her anahtar, hash fonksiyonu tarafından sayısal bir özete dönüştürülür. Basitleştirilmiş biçimiyle yerleşim işlemi şöyle gösterilebilir:</p>

\[indeks = hash(anahtar) \bmod kapasite\]

<p>Bu indeks, değerin bellekte hangi kovaya yerleştirileceğini belirler. İki farklı anahtar aynı indeksi üretirse <strong>çakışma</strong> oluşur. Hash haritası uygulamaları bu durumu zincirleme veya açık adresleme gibi yöntemlerle çözer.</p>

<p>İyi dağılım sağlayan bir hash fonksiyonunda ekleme, arama ve silme işlemlerinin ortalama zaman karmaşıklığı $O(1)$ kabul edilir. Ancak çok sayıda çakışmanın yaşandığı kötü durumda karmaşıklık $O(n)$ seviyesine çıkabilir.</p>

<table>
  <thead>
    <tr>
      <th>Koleksiyon</th>
      <th>Erişim yöntemi</th>
      <th style="text-align: right">Ortalama arama</th>
      <th>Sıralama</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">Vec&lt;T&gt;</code></td>
      <td>Sayısal indeks</td>
      <td style="text-align: right">$O(n)$</td>
      <td>Ekleme sırasını korur</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">HashMap&lt;K, V&gt;</code></td>
      <td>Benzersiz anahtar</td>
      <td style="text-align: right">$O(1)$</td>
      <td>Garanti edilmez</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">BTreeMap&lt;K, V&gt;</code></td>
      <td>Sıralı anahtar</td>
      <td style="text-align: right">$O(\log n)$</td>
      <td>Anahtara göre sıralıdır</td>
    </tr>
  </tbody>
</table>

<h2 id="rust-ile-hashmap-oluşturmak">Rust ile HashMap oluşturmak</h2>

<p><code class="language-plaintext highlighter-rouge">HashMap</code>, standart kütüphanenin ön hazırlık modülünde otomatik olarak bulunmaz; önce içe aktarılmalıdır. Aşağıdaki kod, ürün adlarını fiyatlarla eşleştirir:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">collections</span><span class="p">::</span><span class="n">HashMap</span><span class="p">;</span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="k">mut</span> <span class="n">fiyatlar</span> <span class="o">=</span> <span class="nn">HashMap</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>

    <span class="n">fiyatlar</span><span class="nf">.insert</span><span class="p">(</span><span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"Klavye"</span><span class="p">),</span> <span class="mi">1250</span><span class="p">);</span>
    <span class="n">fiyatlar</span><span class="nf">.insert</span><span class="p">(</span><span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"Fare"</span><span class="p">),</span> <span class="mi">700</span><span class="p">);</span>
    <span class="n">fiyatlar</span><span class="nf">.insert</span><span class="p">(</span><span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"Monitör"</span><span class="p">),</span> <span class="mi">8200</span><span class="p">);</span>

    <span class="k">if</span> <span class="k">let</span> <span class="nf">Some</span><span class="p">(</span><span class="n">fiyat</span><span class="p">)</span> <span class="o">=</span> <span class="n">fiyatlar</span><span class="nf">.get</span><span class="p">(</span><span class="s">"Klavye"</span><span class="p">)</span> <span class="p">{</span>
        <span class="nd">println!</span><span class="p">(</span><span class="s">"Klavye fiyatı: {fiyat} TL"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">insert</code>, haritayı değiştirdiği için değişken <code class="language-plaintext highlighter-rouge">mut</code> olarak tanımlanmıştır. <code class="language-plaintext highlighter-rouge">get</code> metodu ise anahtar bulunamayabileceğinden <code class="language-plaintext highlighter-rouge">Option&lt;&amp;V&gt;</code> döndürür. Böylece Rust, “olmayan değeri kullandın, program çöktü” sürprizini kontrollü bir seçime dönüştürür.</p>

<h2 id="sahiplik-kuralları-haritayı-nasıl-etkiler">Sahiplik kuralları haritayı nasıl etkiler?</h2>

<p><code class="language-plaintext highlighter-rouge">i32</code> gibi <code class="language-plaintext highlighter-rouge">Copy</code> özelliğine sahip türler haritaya kopyalanır. <code class="language-plaintext highlighter-rouge">String</code> gibi kopyalanmayan türlerde ise sahiplik varsayılan olarak <code class="language-plaintext highlighter-rouge">HashMap</code> yapısına taşınır:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">collections</span><span class="p">::</span><span class="n">HashMap</span><span class="p">;</span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">anahtar</span> <span class="o">=</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"tema"</span><span class="p">);</span>
    <span class="k">let</span> <span class="n">deger</span> <span class="o">=</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"karanlik"</span><span class="p">);</span>
    <span class="k">let</span> <span class="k">mut</span> <span class="n">ayarlar</span> <span class="o">=</span> <span class="nn">HashMap</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>

    <span class="n">ayarlar</span><span class="nf">.insert</span><span class="p">(</span><span class="n">anahtar</span><span class="p">,</span> <span class="n">deger</span><span class="p">);</span>

    <span class="c1">// println!("{anahtar}"); // Hata: sahiplik taşındı.</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span> <span class="n">ayarlar</span><span class="nf">.get</span><span class="p">(</span><span class="s">"tema"</span><span class="p">));</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Eklemeden sonra <code class="language-plaintext highlighter-rouge">anahtar</code> ve <code class="language-plaintext highlighter-rouge">deger</code> artık kullanılamaz; onların yeni sahibi <code class="language-plaintext highlighter-rouge">ayarlar</code> değişkenidir. Harita kapsam dışına çıktığında içindeki veriler de güvenli biçimde temizlenir. Verilerin sahipliğini taşımak istemiyorsak referans saklayabiliriz; ancak bu kez referansların haritadan daha uzun yaşaması gerekir.</p>

<table>
  <thead>
    <tr>
      <th>Ekleme biçimi</th>
      <th>Sonuç</th>
      <th>Dikkat edilmesi gereken</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sahip olunan <code class="language-plaintext highlighter-rouge">String</code></td>
      <td>Sahiplik haritaya taşınır</td>
      <td>Eski değişken kullanılamaz</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">i32</code>, <code class="language-plaintext highlighter-rouge">bool</code> gibi <code class="language-plaintext highlighter-rouge">Copy</code> türü</td>
      <td>Değer kopyalanır</td>
      <td>Kaynak değişken kullanılabilir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&amp;str</code> veya başka referans</td>
      <td>Yalnızca ödünç alınır</td>
      <td>Yaşam süresi geçerli kalmalıdır</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">clone()</code> ile ekleme</td>
      <td>Bağımsız kopya üretilir</td>
      <td>Ek bellek ve işlem maliyeti doğurur</td>
    </tr>
  </tbody>
</table>

<h2 id="değerleri-güncelleme-stratejileri">Değerleri güncelleme stratejileri</h2>

<p>Aynı anahtarla tekrar <code class="language-plaintext highlighter-rouge">insert</code> çağrılırsa eski değer yenisiyle değiştirilir. Anahtar yalnızca yoksa değer eklemek için <code class="language-plaintext highlighter-rouge">entry</code> API’si kullanılır. Bu API, kelime sayacı gibi senaryolarda oldukça zariftir:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">use</span> <span class="nn">std</span><span class="p">::</span><span class="nn">collections</span><span class="p">::</span><span class="n">HashMap</span><span class="p">;</span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">metin</span> <span class="o">=</span> <span class="s">"rust guvenli rust hizli rust eglenceli"</span><span class="p">;</span>
    <span class="k">let</span> <span class="k">mut</span> <span class="n">sayac</span> <span class="o">=</span> <span class="nn">HashMap</span><span class="p">::</span><span class="nf">new</span><span class="p">();</span>

    <span class="k">for</span> <span class="n">kelime</span> <span class="k">in</span> <span class="n">metin</span><span class="nf">.split_whitespace</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">let</span> <span class="n">adet</span> <span class="o">=</span> <span class="n">sayac</span><span class="nf">.entry</span><span class="p">(</span><span class="n">kelime</span><span class="p">)</span><span class="nf">.or_insert</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
        <span class="o">*</span><span class="n">adet</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="nd">println!</span><span class="p">(</span><span class="s">"{sayac:?}"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">or_insert(0)</code>, ilgili değere değiştirilebilir bir referans verir. <code class="language-plaintext highlighter-rouge">*adet += 1</code> ifadesi bu referansın gösterdiği sayıyı artırır. Ödünç alma kuralları nedeniyle aynı anda harita üzerinde çakışan değiştirilebilir erişimler oluşturulamaz; böylece iterator geçersizliği ve veri yarışı gibi hatalar daha derleme aşamasında engellenir.</p>

<p>Sonuç olarak <code class="language-plaintext highlighter-rouge">HashMap</code>, hızlı anahtar tabanlı erişim sağlarken Rust’ın sahiplik modeli verilerin kime ait olduğunu açıkça belirler. Ayarlar, önbellekler, sayaçlar ve kullanıcı kayıtları için güçlü bir seçimdir; fakat sıralama gerekiyorsa <code class="language-plaintext highlighter-rouge">BTreeMap</code>, yalnızca ardışık veriler tutulacaksa <code class="language-plaintext highlighter-rouge">Vec</code> daha uygun olabilir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Rust" /><category term="HashMap" /><category term="Sahiplik" /><summary type="html"><![CDATA[Bir telefon rehberinde kişileri sayfa sayfa aramak yerine isimlerini doğrudan yazarak numaralarına ulaştığınızı düşünün. Hash haritaları tam olarak bu fikri programlama dünyasına taşır: Veriler, anahtar ve değer çiftleri hâlinde saklanır. Rust’ın HashMap koleksiyonu ise bu pratik yapıyı dilin sahiplik, ödünç alma ve yaşam süresi kurallarıyla birleştirerek hem hızlı hem de güvenli veri yönetimi sunar.]]></summary></entry><entry><title type="html">Rust Yapıları: Struct ve impl ile Güçlü Veri Modelleri</title><link href="https://sonsuzus.github.io/posts/rust-yapilari-struct-ve-impl-ile-guclu-veri-modelleri/" rel="alternate" type="text/html" title="Rust Yapıları: Struct ve impl ile Güçlü Veri Modelleri" /><published>2026-08-03T00:00:00+00:00</published><updated>2026-08-03T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/rust-yapilari-struct-ve-impl-ile-guclu-veri-modelleri</id><content type="html" xml:base="https://sonsuzus.github.io/posts/rust-yapilari-struct-ve-impl-ile-guclu-veri-modelleri/"><![CDATA[<p>Bir uygulamada kullanıcı adı, yaş, e-posta adresi ve aktiflik durumu gibi birbirleriyle ilişkili değerleri ayrı değişkenlerde tutmak mümkündür. Ancak proje büyüdükçe bu yaklaşım, çekmeceleri etiketlenmemiş bir dolaba dönüşür. Rust dilindeki <code class="language-plaintext highlighter-rouge">struct</code> yapıları, farklı tiplerdeki verileri anlamlı bir isim altında birleştirerek kendi veri tiplerimizi oluşturmamızı sağlar.
``</p>
<h2 id="struct-nedir">Struct Nedir?</h2>

<p><code class="language-plaintext highlighter-rouge">struct</code>, belirli bir kavramı temsil eden alanların tek bir veri tipi altında toplanmasıdır. Örneğin bir kullanıcı; metin biçiminde ada, sayısal yaşa ve mantıksal aktiflik durumuna sahip olabilir. Bu değerlerin tipleri farklı olsa da aynı varlığı tanımlar.</p>

<p>Matematiksel açıdan bir yapı, farklı kümelerin Kartezyen çarpımından seçilen bir kayıt gibi düşünülebilir:</p>

\[Kullanici = String \times u8 \times String \times bool\]

<p>Buradaki her kullanıcı, bu kümelerden gelen değerlerin oluşturduğu bir bütündür. Struct kullanmak yalnızca verileri paketlemez; alan adları sayesinde verinin anlamını da kodun içine taşır.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Avantaj</th>
      <th>Dezavantaj</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ayrı değişkenler</td>
      <td>Küçük örneklerde hızlıdır</td>
      <td>İlişkiler kolayca kaybolur</td>
    </tr>
    <tr>
      <td>Tuple</td>
      <td>Değerleri gruplar</td>
      <td>Alanların anlamı belirsiz olabilir</td>
    </tr>
    <tr>
      <td>Struct</td>
      <td>İsimlendirilmiş ve güvenli model sunar</td>
      <td>Önceden tip tanımı gerektirir</td>
    </tr>
  </tbody>
</table>

<h2 id="i̇lk-yapımızı-tanımlayalım">İlk Yapımızı Tanımlayalım</h2>

<p>Aşağıdaki yapı, bir uygulama kullanıcısını modellemektedir:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="n">Kullanici</span> <span class="p">{</span>
    <span class="n">ad</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span>
    <span class="n">yas</span><span class="p">:</span> <span class="nb">u8</span><span class="p">,</span>
    <span class="n">eposta</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span>
    <span class="n">aktif</span><span class="p">:</span> <span class="nb">bool</span><span class="p">,</span>
<span class="p">}</span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">kullanici</span> <span class="o">=</span> <span class="n">Kullanici</span> <span class="p">{</span>
        <span class="n">ad</span><span class="p">:</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"Ada"</span><span class="p">),</span>
        <span class="n">yas</span><span class="p">:</span> <span class="mi">28</span><span class="p">,</span>
        <span class="n">eposta</span><span class="p">:</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"ada@example.com"</span><span class="p">),</span>
        <span class="n">aktif</span><span class="p">:</span> <span class="k">true</span><span class="p">,</span>
    <span class="p">};</span>

    <span class="nd">println!</span><span class="p">(</span><span class="s">"Kullanıcı: {}"</span><span class="p">,</span> <span class="n">kullanici</span><span class="py">.ad</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Her alanın tipi derleme zamanında bellidir. Örneğin <code class="language-plaintext highlighter-rouge">yas</code> alanına yanlışlıkla bir metin atanırsa Rust programı çalıştırmadan önce hata verir. Bu özellik, veri modelini aynı zamanda bir güvenlik sözleşmesine dönüştürür.</p>

<p>Bir örneğin değiştirilebilmesi için tamamının <code class="language-plaintext highlighter-rouge">mut</code> olarak tanımlanması gerekir:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="k">mut</span> <span class="n">kullanici</span> <span class="o">=</span> <span class="n">Kullanici</span> <span class="p">{</span>
    <span class="n">ad</span><span class="p">:</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"Ece"</span><span class="p">),</span>
    <span class="n">yas</span><span class="p">:</span> <span class="mi">24</span><span class="p">,</span>
    <span class="n">eposta</span><span class="p">:</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"ece@example.com"</span><span class="p">),</span>
    <span class="n">aktif</span><span class="p">:</span> <span class="k">false</span><span class="p">,</span>
<span class="p">};</span>

<span class="n">kullanici</span><span class="py">.aktif</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span>
</code></pre></div></div>

<p>Rust, yalnızca tek bir alanı <code class="language-plaintext highlighter-rouge">mut</code> yapmaya izin vermez. Değişebilirlik struct örneğinin tamamına aittir.</p>

<h2 id="impl-ile-yapıya-davranış-kazandırmak">impl ile Yapıya Davranış Kazandırmak</h2>

<p>Veri modellemek çoğu zaman yeterli değildir; modelin davranışları da olmalıdır. <code class="language-plaintext highlighter-rouge">impl</code> bloğu, belirli bir struct için metot ve ilişkili fonksiyon tanımlamamızı sağlar.</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">impl</span> <span class="n">Kullanici</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">yeni</span><span class="p">(</span><span class="n">ad</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="n">yas</span><span class="p">:</span> <span class="nb">u8</span><span class="p">,</span> <span class="n">eposta</span><span class="p">:</span> <span class="nb">String</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="k">Self</span> <span class="p">{</span>
        <span class="k">Self</span> <span class="p">{</span>
            <span class="n">ad</span><span class="p">,</span>
            <span class="n">yas</span><span class="p">,</span>
            <span class="n">eposta</span><span class="p">,</span>
            <span class="n">aktif</span><span class="p">:</span> <span class="k">true</span><span class="p">,</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="k">fn</span> <span class="nf">yetiskin_mi</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">bool</span> <span class="p">{</span>
        <span class="k">self</span><span class="py">.yas</span> <span class="o">&gt;=</span> <span class="mi">18</span>
    <span class="p">}</span>

    <span class="k">fn</span> <span class="nf">devre_disi_birak</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span> <span class="k">self</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">self</span><span class="py">.aktif</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">yeni</code>, bir ilişkili fonksiyondur; çağrılmak için mevcut bir nesneye ihtiyaç duymaz. <code class="language-plaintext highlighter-rouge">Self</code>, <code class="language-plaintext highlighter-rouge">Kullanici</code> tipinin kısa yazımıdır. <code class="language-plaintext highlighter-rouge">yetiskin_mi</code> metodu <code class="language-plaintext highlighter-rouge">&amp;self</code> ile veriyi yalnızca ödünç alır. <code class="language-plaintext highlighter-rouge">devre_disi_birak</code> ise <code class="language-plaintext highlighter-rouge">&amp;mut self</code> kullandığı için örneği değiştirebilir.</p>

<table>
  <thead>
    <tr>
      <th>Alıcı</th>
      <th>Yetki</th>
      <th>Tipik kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&amp;self</code></td>
      <td>Salt okunur erişim</td>
      <td>Bilgi sorgulama</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&amp;mut self</code></td>
      <td>Değiştirme</td>
      <td>Durum güncelleme</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">self</code></td>
      <td>Sahipliği devralma</td>
      <td>Nesneyi tüketme</td>
    </tr>
    <tr>
      <td>Alıcı yok</td>
      <td>Örneğe ihtiyaç duymaz</td>
      <td>Kurucu fonksiyon</td>
    </tr>
  </tbody>
</table>

<p>Metotlar şu şekilde kullanılabilir:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="k">mut</span> <span class="n">kisi</span> <span class="o">=</span> <span class="nn">Kullanici</span><span class="p">::</span><span class="nf">yeni</span><span class="p">(</span>
    <span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"Mert"</span><span class="p">),</span>
    <span class="mi">20</span><span class="p">,</span>
    <span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"mert@example.com"</span><span class="p">),</span>
<span class="p">);</span>

<span class="nd">println!</span><span class="p">(</span><span class="s">"Yetişkin mi? {}"</span><span class="p">,</span> <span class="n">kisi</span><span class="nf">.yetiskin_mi</span><span class="p">());</span>
<span class="n">kisi</span><span class="nf">.devre_disi_birak</span><span class="p">();</span>
</code></pre></div></div>

<h2 id="neden-önemlidir">Neden Önemlidir?</h2>

<p>İyi tasarlanmış bir struct, programın iş kurallarını görünür hâle getirir. Kullanıcı, ürün, sipariş veya oyun karakteri gibi kavramlar; alanları ve davranışlarıyla bağımsız modellere dönüşür. Böylece fonksiyonlara uzun parametre listeleri taşımak yerine tek ve anlamlı bir değer gönderilir.</p>

<p>Struct ve <code class="language-plaintext highlighter-rouge">impl</code> birlikteliği, Rust’ta veri ile davranış arasında düzenli bir bağ kurar. Sonuç; okunabilir, tip güvenli ve büyümeye hazır koddur. Kısacası struct verinin iskeletiyse, <code class="language-plaintext highlighter-rouge">impl</code> o iskelete hareket kazandıran kaslardır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Rust" /><category term="Struct" /><category term="Veri Modelleme" /><summary type="html"><![CDATA[Bir uygulamada kullanıcı adı, yaş, e-posta adresi ve aktiflik durumu gibi birbirleriyle ilişkili değerleri ayrı değişkenlerde tutmak mümkündür. Ancak proje büyüdükçe bu yaklaşım, çekmeceleri etiketlenmemiş bir dolaba dönüşür. Rust dilindeki struct yapıları, farklı tiplerdeki verileri anlamlı bir isim altında birleştirerek kendi veri tiplerimizi oluşturmamızı sağlar.]]></summary></entry><entry><title type="html">Rust’ta Enum ve Pattern Matching: Tüm Olasılıkları Yakalamak</title><link href="https://sonsuzus.github.io/posts/rustta-enum-ve-pattern-matching-tum-olasiliklari-yakalamak/" rel="alternate" type="text/html" title="Rust’ta Enum ve Pattern Matching: Tüm Olasılıkları Yakalamak" /><published>2026-08-03T00:00:00+00:00</published><updated>2026-08-03T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/rustta-enum-ve-pattern-matching-tum-olasiliklari-yakalamak</id><content type="html" xml:base="https://sonsuzus.github.io/posts/rustta-enum-ve-pattern-matching-tum-olasiliklari-yakalamak/"><![CDATA[<p>Bir verinin yalnızca tek bir biçimi olmak zorunda değildir. Örneğin bir ödeme başarılı, reddedilmiş veya hâlâ bekliyor olabilir. Bu durumları metinlerle temsil etmek mümkün olsa da küçük bir yazım hatası programın mantığını bozabilir. Rust’ın <code class="language-plaintext highlighter-rouge">enum</code> ve <code class="language-plaintext highlighter-rouge">match</code> araçları, farklı veri varyasyonlarını güvenli biçimde modelleyerek derleyiciyi adeta hata avlayan bir ekip arkadaşına dönüştürür.
``</p>

<h2 id="enum-neden-gereklidir">Enum neden gereklidir?</h2>

<p>Enum, bir değerin önceden belirlenmiş varyasyonlardan <strong>yalnızca biri</strong> olabileceğini ifade eden veri tipidir. Matematiksel olarak bir enum’u ayrık birleşim biçiminde düşünebiliriz:</p>

\[Durum = Bekliyor \;|\; Basarili \;|\; Reddedildi\]

<table>
  <tbody>
    <tr>
      <td>Buradaki $</td>
      <td>$ işareti, “bu seçeneklerden biri” anlamına gelir. Her varyasyon kendi verisini de taşıyabilir. Böylece yalnızca durumun adı değil, o durumla ilişkili bilgi de aynı yapı içinde güvenli şekilde saklanır.</td>
    </tr>
  </tbody>
</table>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">enum</span> <span class="n">OdemeDurumu</span> <span class="p">{</span>
    <span class="n">Bekliyor</span><span class="p">,</span>
    <span class="n">Basarili</span> <span class="p">{</span> <span class="n">islem_no</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="n">tutar</span><span class="p">:</span> <span class="nb">f64</span> <span class="p">},</span>
    <span class="nf">Reddedildi</span><span class="p">(</span><span class="nb">String</span><span class="p">),</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu enum’da <code class="language-plaintext highlighter-rouge">Bekliyor</code> ek bilgi taşımaz. <code class="language-plaintext highlighter-rouge">Basarili</code>, işlem numarası ile tutarı; <code class="language-plaintext highlighter-rouge">Reddedildi</code> ise hata açıklamasını taşır. Birbirinden kopuk değişkenler oluşturmak yerine verinin şekli doğrudan tipe işlenmiştir.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th style="text-align: right">Tip güvenliği</th>
      <th style="text-align: right">Geçersiz durum riski</th>
      <th style="text-align: right">Ek veri taşıma</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Metin (<code class="language-plaintext highlighter-rouge">String</code>)</td>
      <td style="text-align: right">Düşük</td>
      <td style="text-align: right">Yüksek</td>
      <td style="text-align: right">Elle yönetilir</td>
    </tr>
    <tr>
      <td>Sayısal kod</td>
      <td style="text-align: right">Orta</td>
      <td style="text-align: right">Orta</td>
      <td style="text-align: right">Ayrı değişken gerekir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">enum</code></td>
      <td style="text-align: right">Yüksek</td>
      <td style="text-align: right">Düşük</td>
      <td style="text-align: right">Varyasyon içinde taşınır</td>
    </tr>
  </tbody>
</table>

<p>Metin kullanan bir sistemde <code class="language-plaintext highlighter-rouge">"başarılı"</code>, <code class="language-plaintext highlighter-rouge">"Başarılı"</code> ve yanlışlıkla yazılan <code class="language-plaintext highlighter-rouge">"başarlı"</code> farklı değerlerdir. Enum kullanıldığında ise derleyici yalnızca tanımlanmış varyasyonlara izin verir.</p>

<h2 id="match-ile-varyasyonları-açmak">Match ile varyasyonları açmak</h2>

<p><code class="language-plaintext highlighter-rouge">match</code>, bir enum değerini varyasyonlarına göre inceleyen ve uygun kod dalını çalıştıran ifadedir. Aynı zamanda varyasyonun içindeki verileri <strong>desen eşleştirme</strong> yoluyla çıkarabilir:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">raporla</span><span class="p">(</span><span class="n">durum</span><span class="p">:</span> <span class="n">OdemeDurumu</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">String</span> <span class="p">{</span>
    <span class="k">match</span> <span class="n">durum</span> <span class="p">{</span>
        <span class="nn">OdemeDurumu</span><span class="p">::</span><span class="n">Bekliyor</span> <span class="k">=&gt;</span> <span class="p">{</span>
            <span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"Ödeme henüz tamamlanmadı."</span><span class="p">)</span>
        <span class="p">}</span>
        <span class="nn">OdemeDurumu</span><span class="p">::</span><span class="n">Basarili</span> <span class="p">{</span> <span class="n">islem_no</span><span class="p">,</span> <span class="n">tutar</span> <span class="p">}</span> <span class="k">=&gt;</span> <span class="p">{</span>
            <span class="nd">format!</span><span class="p">(</span><span class="s">"{} numaralı işlem tamamlandı: {:.2} TL"</span><span class="p">,</span> <span class="n">islem_no</span><span class="p">,</span> <span class="n">tutar</span><span class="p">)</span>
        <span class="p">}</span>
        <span class="nn">OdemeDurumu</span><span class="p">::</span><span class="nf">Reddedildi</span><span class="p">(</span><span class="n">neden</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="p">{</span>
            <span class="nd">format!</span><span class="p">(</span><span class="s">"Ödeme reddedildi: {}"</span><span class="p">,</span> <span class="n">neden</span><span class="p">)</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">islem_no</code>, <code class="language-plaintext highlighter-rouge">tutar</code> ve <code class="language-plaintext highlighter-rouge">neden</code> değişkenleri yalnızca ilgili desen eşleştiğinde oluşturulur. Ayrıca <code class="language-plaintext highlighter-rouge">match</code> bir ifade olduğu için her dalın ürettiği <code class="language-plaintext highlighter-rouge">String</code>, fonksiyonun dönüş değeri olarak kullanılabilir.</p>

<h2 id="eksiksizlik-denetimi">Eksiksizlik denetimi</h2>

<p>Rust’taki <code class="language-plaintext highlighter-rouge">match</code> ifadesinin en güçlü özelliği <strong>exhaustiveness</strong>, yani eksiksizlik kontrolüdür. Enum’un varyasyon sayısı $n$ ise güvenli bir eşleştirme bütün olasılık kümesini kapsamalıdır:</p>

\[Kapsanan\ Varyasyonlar = n\]

<p>Örneğin <code class="language-plaintext highlighter-rouge">Reddedildi</code> dalını silersek kod derlenmez. Derleyici, hangi desenin eksik olduğunu bildirir. Daha sonra enum’a <code class="language-plaintext highlighter-rouge">IadeEdildi</code> varyasyonu eklendiğinde de ilgili tüm <code class="language-plaintext highlighter-rouge">match</code> ifadeleri yeniden kontrol edilir. Böylece yeni bir özelliğin unutulmuş kod yolları oluşturması engellenir.</p>

<p>Genel bir yakalama için <code class="language-plaintext highlighter-rouge">_</code> deseni kullanılabilir:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">match</span> <span class="n">durum</span> <span class="p">{</span>
    <span class="nn">OdemeDurumu</span><span class="p">::</span><span class="n">Basarili</span> <span class="p">{</span> <span class="n">tutar</span><span class="p">,</span> <span class="o">..</span> <span class="p">}</span> <span class="k">=&gt;</span> <span class="nd">println!</span><span class="p">(</span><span class="s">"Kazanç: {tutar}"</span><span class="p">),</span>
    <span class="n">_</span> <span class="k">=&gt;</span> <span class="nd">println!</span><span class="p">(</span><span class="s">"Henüz kazanç oluşmadı."</span><span class="p">),</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">..</code>, varyasyondaki kullanılmayan alanları yok sayar; <code class="language-plaintext highlighter-rouge">_</code> ise kalan bütün varyasyonları eşleştirir. Ancak <code class="language-plaintext highlighter-rouge">_</code> aşırı kullanılırsa enum’a sonradan eklenen varyasyonlar sessizce bu dala düşebilir. Kritik iş kurallarında varyasyonları açıkça yazmak daha güvenlidir.</p>

<h2 id="koruyucular-ve-daha-hassas-desenler">Koruyucular ve daha hassas desenler</h2>

<p>Desenlere <code class="language-plaintext highlighter-rouge">if</code> koruyucuları eklenerek aynı varyasyon farklı koşullara ayrılabilir:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">match</span> <span class="n">durum</span> <span class="p">{</span>
    <span class="nn">OdemeDurumu</span><span class="p">::</span><span class="n">Basarili</span> <span class="p">{</span> <span class="n">tutar</span><span class="p">,</span> <span class="o">..</span> <span class="p">}</span> <span class="k">if</span> <span class="n">tutar</span> <span class="o">&gt;=</span> <span class="mf">10_000.0</span> <span class="k">=&gt;</span> <span class="p">{</span>
        <span class="nd">println!</span><span class="p">(</span><span class="s">"Yüksek tutarlı işlem kontrol edilmeli."</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="nn">OdemeDurumu</span><span class="p">::</span><span class="n">Basarili</span> <span class="p">{</span> <span class="n">tutar</span><span class="p">,</span> <span class="o">..</span> <span class="p">}</span> <span class="k">=&gt;</span> <span class="nd">println!</span><span class="p">(</span><span class="s">"Onaylanan tutar: {tutar}"</span><span class="p">),</span>
    <span class="nn">OdemeDurumu</span><span class="p">::</span><span class="n">Bekliyor</span> <span class="k">=&gt;</span> <span class="nd">println!</span><span class="p">(</span><span class="s">"Bekleniyor..."</span><span class="p">),</span>
    <span class="nn">OdemeDurumu</span><span class="p">::</span><span class="nf">Reddedildi</span><span class="p">(</span><span class="n">neden</span><span class="p">)</span> <span class="k">=&gt;</span> <span class="nd">println!</span><span class="p">(</span><span class="s">"Hata: {neden}"</span><span class="p">),</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Enum verinin hangi biçimlerde bulunabileceğini, <code class="language-plaintext highlighter-rouge">match</code> ise her biçimde ne yapılacağını tanımlar. İkisi birlikte kullanıldığında geçersiz durumlar azalır, dallanma mantığı okunabilir hâle gelir ve unutulan olasılıklar çalışma zamanına ulaşmadan yakalanır. Kısacası derleyici yalnızca kodu çevirmekle kalmaz; olasılıkları sizinle birlikte sayar.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Rust" /><category term="Enum" /><category term="Pattern Matching" /><summary type="html"><![CDATA[Bir verinin yalnızca tek bir biçimi olmak zorunda değildir. Örneğin bir ödeme başarılı, reddedilmiş veya hâlâ bekliyor olabilir. Bu durumları metinlerle temsil etmek mümkün olsa da küçük bir yazım hatası programın mantığını bozabilir. Rust’ın enum ve match araçları, farklı veri varyasyonlarını güvenli biçimde modelleyerek derleyiciyi adeta hata avlayan bir ekip arkadaşına dönüştürür.]]></summary></entry><entry><title type="html">Rust’ta String Mimarisi: String, &amp;amp;str ve UTF-8’in Perde Arkası</title><link href="https://sonsuzus.github.io/posts/rustta-string-mimarisi-string-str-ve-utf-8in-perde-arkasi/" rel="alternate" type="text/html" title="Rust’ta String Mimarisi: String, &amp;amp;str ve UTF-8’in Perde Arkası" /><published>2026-08-03T00:00:00+00:00</published><updated>2026-08-03T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/rustta-string-mimarisi-string-str-ve-utf-8in-perde-arkasi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/rustta-string-mimarisi-string-str-ve-utf-8in-perde-arkasi/"><![CDATA[<p>Rust’ta metinlerle çalışmaya başlayanların karşısına kısa sürede iki oyuncu çıkar: <code class="language-plaintext highlighter-rouge">String</code> ve <code class="language-plaintext highlighter-rouge">&amp;str</code>. İlk bakışta ikisi de yazı tutuyor gibi görünür; ancak bellek yönetimi, sahiplik ve boyut açısından aralarında önemli farklar vardır. Bu ayrımı anlamak, hem gereksiz kopyalamaları önler hem de Rust’ın ödünç alma sistemini çok daha anlaşılır hâle getirir.
``</p>
<h2 id="i̇ki-farklı-metin-görünümü">İki Farklı Metin Görünümü</h2>

<p><code class="language-plaintext highlighter-rouge">String</code>, UTF-8 kodlanmış metni heap üzerinde saklayan, büyüyüp küçülebilen ve verisinin sahibi olan bir koleksiyondur. Yapısal olarak <code class="language-plaintext highlighter-rouge">Vec&lt;u8&gt;</code> ile benzer bir mantığa sahiptir ve üç temel bilgi taşır:</p>

<ul>
  <li>Heap üzerindeki veriyi gösteren işaretçi</li>
  <li>Kullanılan bayt sayısını belirten uzunluk</li>
  <li>Ayrılmış toplam alanı belirten kapasite</li>
</ul>

<p>Bu ilişkiyi kabaca şöyle gösterebiliriz:</p>

\[0 \leq \text{length} \leq \text{capacity}\]

<p>Metne yeni karakterler eklendiğinde uzunluk kapasiteyi aşarsa daha büyük bir bellek alanı ayrılır ve mevcut veri taşınabilir. Dolayısıyla büyütme işlemi her zaman ücretsiz değildir.</p>

<p><code class="language-plaintext highlighter-rouge">str</code> ise dinamik boyutlu bir türdür; derleme anında kaç bayt tutacağı bilinmez. Bu nedenle çoğunlukla doğrudan <code class="language-plaintext highlighter-rouge">str</code> değil, <code class="language-plaintext highlighter-rouge">&amp;str</code> biçiminde kullanılır. Bir <code class="language-plaintext highlighter-rouge">&amp;str</code>, metin verisine işaret eden ödünç alınmış bir görünüm ile görünümün bayt uzunluğundan oluşur. Verinin sahibi değildir ve kapsam sona erdiğinde metni serbest bırakmaz.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th><code class="language-plaintext highlighter-rouge">String</code></th>
      <th><code class="language-plaintext highlighter-rouge">&amp;str</code></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sahiplik</td>
      <td>Verinin sahibidir</td>
      <td>Veriyi ödünç alır</td>
    </tr>
    <tr>
      <td>Boyut</td>
      <td>Değişebilir</td>
      <td>Görünüm boyunca sabittir</td>
    </tr>
    <tr>
      <td>Bellek</td>
      <td>Genellikle heap</td>
      <td>Heap, stack veya program verisi olabilir</td>
    </tr>
    <tr>
      <td>Yapı</td>
      <td>İşaretçi, uzunluk, kapasite</td>
      <td>İşaretçi, uzunluk</td>
    </tr>
    <tr>
      <td>Tipik kullanım</td>
      <td>Metin üretmek ve değiştirmek</td>
      <td>Metni okumak ve fonksiyonlara aktarmak</td>
    </tr>
  </tbody>
</table>

<h2 id="oluşturma-ve-ödünç-alma">Oluşturma ve Ödünç Alma</h2>

<p>Aşağıdaki örnekte değiştirilebilir bir <code class="language-plaintext highlighter-rouge">String</code> oluşturuluyor, büyütülüyor ve ardından bu veriye <code class="language-plaintext highlighter-rouge">&amp;str</code> görünümü alınıyor:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">kelime_sayisi</span><span class="p">(</span><span class="n">metin</span><span class="p">:</span> <span class="o">&amp;</span><span class="nb">str</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">usize</span> <span class="p">{</span>
    <span class="n">metin</span><span class="nf">.split_whitespace</span><span class="p">()</span><span class="nf">.count</span><span class="p">()</span>
<span class="p">}</span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="k">mut</span> <span class="n">mesaj</span> <span class="o">=</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"Merhaba"</span><span class="p">);</span>
    <span class="n">mesaj</span><span class="nf">.push_str</span><span class="p">(</span><span class="s">", Rust dünyası!"</span><span class="p">);</span>

    <span class="k">let</span> <span class="n">gorunum</span><span class="p">:</span> <span class="o">&amp;</span><span class="nb">str</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">mesaj</span><span class="p">;</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span> <span class="n">gorunum</span><span class="p">);</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"Kelime: {}"</span><span class="p">,</span> <span class="nf">kelime_sayisi</span><span class="p">(</span><span class="o">&amp;</span><span class="n">mesaj</span><span class="p">));</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">kelime_sayisi</code> parametresinin <code class="language-plaintext highlighter-rouge">&amp;str</code> olması önemlidir. Böylece fonksiyon hem <code class="language-plaintext highlighter-rouge">String</code> içinden alınan dilimleri hem de doğrudan yazılmış metin sabitlerini kabul eder. <code class="language-plaintext highlighter-rouge">&amp;String</code> kullanmak mümkün olsa da daha az esnek bir API ortaya çıkarır.</p>

<h2 id="utf-8-karakter-sayısı-bayt-sayısı-değildir">UTF-8: Karakter Sayısı Bayt Sayısı Değildir</h2>

<p>Rust stringleri geçerli UTF-8 olmak zorundadır. ASCII karakterleri genellikle bir bayt kullanırken Türkçe karakterler veya emojiler birden fazla bayt kullanabilir. Bu nedenle genel olarak:</p>

\[\text{bayt sayısı} \geq \text{Unicode karakter sayısı}\]

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">let</span> <span class="n">metin</span> <span class="o">=</span> <span class="s">"çağrı 🦀"</span><span class="p">;</span>

    <span class="nd">println!</span><span class="p">(</span><span class="s">"Bayt: {}"</span><span class="p">,</span> <span class="n">metin</span><span class="nf">.len</span><span class="p">());</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"Karakter: {}"</span><span class="p">,</span> <span class="n">metin</span><span class="nf">.chars</span><span class="p">()</span><span class="nf">.count</span><span class="p">());</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">len()</code> kullanıcıların gördüğü karakterleri değil, UTF-8 baytlarını sayar. Rust’ın <code class="language-plaintext highlighter-rouge">metin[0]</code> biçiminde indekslemeye izin vermemesinin nedeni de budur: Bir bayt her zaman bağımsız bir karakter anlamına gelmez.</p>

<p>Dilimleme yapılırken sınırların geçerli UTF-8 karakter sınırlarına denk gelmesi gerekir:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">let</span> <span class="n">metin</span> <span class="o">=</span> <span class="nn">String</span><span class="p">::</span><span class="nf">from</span><span class="p">(</span><span class="s">"İstanbul"</span><span class="p">);</span>
<span class="k">let</span> <span class="n">parca</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">metin</span><span class="p">[</span><span class="mi">0</span><span class="o">..</span><span class="mi">2</span><span class="p">];</span> <span class="c1">// "İ", UTF-8 içinde iki bayttır</span>
<span class="nd">println!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span> <span class="n">parca</span><span class="p">);</span>
</code></pre></div></div>

<p>Yanlış bir bayt sınırı çalışma zamanında paniğe yol açabilir. Güvenli karakter işleme için <code class="language-plaintext highlighter-rouge">chars()</code>, bayt işleme için <code class="language-plaintext highlighter-rouge">bytes()</code> kullanılmalıdır.</p>

<h2 id="hangisini-seçmeliyiz">Hangisini Seçmeliyiz?</h2>

<p>Yeni metin oluşturacak, birleştirecek veya değiştirecekseniz <code class="language-plaintext highlighter-rouge">String</code> doğru araçtır. Yalnızca mevcut metni okuyacak bir fonksiyon yazıyorsanız <code class="language-plaintext highlighter-rouge">&amp;str</code> tercih etmek daha esnek ve ekonomiktir. Kısacası <code class="language-plaintext highlighter-rouge">String</code> metnin ev sahibi, <code class="language-plaintext highlighter-rouge">&amp;str</code> ise anahtarı geçici olarak teslim edilmiş misafiridir. UTF-8 de evin oda planıdır; bayt sınırlarını bilmeden duvarı kırmaya çalışırsanız Rust güvenlik görevlisini, yani paniği, çağırır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Rust" /><category term="String" /><category term="UTF-8" /><summary type="html"><![CDATA[Rust’ta metinlerle çalışmaya başlayanların karşısına kısa sürede iki oyuncu çıkar: String ve &amp;str. İlk bakışta ikisi de yazı tutuyor gibi görünür; ancak bellek yönetimi, sahiplik ve boyut açısından aralarında önemli farklar vardır. Bu ayrımı anlamak, hem gereksiz kopyalamaları önler hem de Rust’ın ödünç alma sistemini çok daha anlaşılır hâle getirir.]]></summary></entry><entry><title type="html">Trait’ler ile Ortak Davranışları Standartlaştırmak</title><link href="https://sonsuzus.github.io/posts/traitler-ile-ortak-davranislari-standartlastirmak/" rel="alternate" type="text/html" title="Trait’ler ile Ortak Davranışları Standartlaştırmak" /><published>2026-08-03T00:00:00+00:00</published><updated>2026-08-03T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/traitler-ile-ortak-davranislari-standartlastirmak</id><content type="html" xml:base="https://sonsuzus.github.io/posts/traitler-ile-ortak-davranislari-standartlastirmak/"><![CDATA[<p>Bir uygulamada kuşlar uçar, uçaklar uçar, hatta yeterince kararlı bir geliştiricinin yazdığı kod bile bazen “uçar”. Bu nesneler birbirinden tamamen farklı veri yapılarına sahip olsa da ortak bir davranışı paylaşabilir. Rust’taki <strong>trait</strong> yapısı, farklı tiplerin sahip olması gereken yetenekleri ortak bir sözleşmeyle tanımlamamızı sağlar. Nesne tabanlı dillerdeki <code class="language-plaintext highlighter-rouge">interface</code> kavramına benzese de varsayılan metotlar, generic kısıtları ve güvenli çok biçimlilik gibi güçlü araçlarla daha geniş bir kullanım alanı sunar.</p>

<p>``</p>

<h2 id="trait-nedir">Trait nedir?</h2>

<p>Trait, bir veri tipinin hangi davranışları sağlayacağını bildiren metot imzaları bütünüdür. Buradaki önemli fikir, tipin <strong>ne olduğundan</strong> çok <strong>ne yapabildiğiyle</strong> ilgilenmektir. Örneğin bir <code class="language-plaintext highlighter-rouge">Kus</code> ve <code class="language-plaintext highlighter-rouge">Ucak</code> aynı alanlara sahip değildir; ancak ikisi de <code class="language-plaintext highlighter-rouge">Ucan</code> davranışını uygulayabilir.</p>

<p>Bir trait’i matematiksel bir sözleşme gibi düşünebiliriz. $T$ bir veri tipi, $D$ ise bir davranış kümesi olsun. Eğer $T$, gerekli bütün metotları sağlıyorsa şu ilişkiyi kurarız:</p>

\[T \models D\]

<p>Yani “$T$ tipi, $D$ davranış sözleşmesini karşılar” deriz. Böylece kodumuz somut tiplere değil, yeteneklere bağımlı hâle gelir.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Trait</th>
      <th>Interface</th>
      <th>Kalıtım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Ortak davranış tanımlar</td>
      <td>Evet</td>
      <td>Evet</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td>Ortak veri alanı taşır</td>
      <td>Hayır</td>
      <td>Genellikle hayır</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td>Birden fazla uygulanabilir</td>
      <td>Evet</td>
      <td>Evet</td>
      <td>Dile bağlı</td>
    </tr>
    <tr>
      <td>Varsayılan metot içerebilir</td>
      <td>Evet</td>
      <td>Dile bağlı</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td>Tipler arasında güçlü bağ kurar</td>
      <td>Hayır</td>
      <td>Hayır</td>
      <td>Evet</td>
    </tr>
  </tbody>
</table>

<h2 id="i̇lk-traitimizi-yazalım">İlk trait’imizi yazalım</h2>

<p>Aşağıdaki örnekte uçabilen nesneler için ortak bir şablon oluşturuyoruz:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">trait</span> <span class="n">Ucan</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">isim</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="o">&amp;</span><span class="nb">str</span><span class="p">;</span>
    <span class="k">fn</span> <span class="nf">hiz</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span><span class="p">;</span>

    <span class="k">fn</span> <span class="nf">bilgi_ver</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="p">{</span>
        <span class="nd">println!</span><span class="p">(</span><span class="s">"{} saatte {} km hızla uçuyor."</span><span class="p">,</span> <span class="k">self</span><span class="nf">.isim</span><span class="p">(),</span> <span class="k">self</span><span class="nf">.hiz</span><span class="p">());</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">struct</span> <span class="n">Kus</span> <span class="p">{</span>
    <span class="n">ad</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span>
    <span class="n">ucus_hizi</span><span class="p">:</span> <span class="nb">u32</span><span class="p">,</span>
<span class="p">}</span>

<span class="k">impl</span> <span class="n">Ucan</span> <span class="k">for</span> <span class="n">Kus</span> <span class="p">{</span>
    <span class="k">fn</span> <span class="nf">isim</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="o">&amp;</span><span class="nb">str</span> <span class="p">{</span>
        <span class="o">&amp;</span><span class="k">self</span><span class="py">.ad</span>
    <span class="p">}</span>

    <span class="k">fn</span> <span class="nf">hiz</span><span class="p">(</span><span class="o">&amp;</span><span class="k">self</span><span class="p">)</span> <span class="k">-&gt;</span> <span class="nb">u32</span> <span class="p">{</span>
        <span class="k">self</span><span class="py">.ucus_hizi</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">isim</code> ve <code class="language-plaintext highlighter-rouge">hiz</code> metotlarının uygulanması zorunludur. <code class="language-plaintext highlighter-rouge">bilgi_ver</code> ise varsayılan bir gövdeye sahiptir; isteyen tip bunu doğrudan kullanabilir, isteyen kendi sürümünü yazabilir. Böylece tekrar azaltılırken davranışın özelleştirilebilirliği korunur.</p>

<h2 id="trait-bound-ile-yetenek-istemek">Trait bound ile yetenek istemek</h2>

<p>Generic bir fonksiyon her tipi kabul edebilir; fakat bazen “Her tip gelsin ama uçmayı bilsin!” demek isteriz. Bunun için <strong>trait bound</strong> kullanılır:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="n">yarisa_kat</span><span class="o">&lt;</span><span class="n">T</span><span class="p">:</span> <span class="n">Ucan</span><span class="o">&gt;</span><span class="p">(</span><span class="n">katilimci</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">T</span><span class="p">)</span> <span class="p">{</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"Yarışmacı: {}"</span><span class="p">,</span> <span class="n">katilimci</span><span class="nf">.isim</span><span class="p">());</span>
    <span class="n">katilimci</span><span class="nf">.bilgi_ver</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">T: Ucan</code>, <code class="language-plaintext highlighter-rouge">T</code> tipinin <code class="language-plaintext highlighter-rouge">Ucan</code> trait’ini uygulaması gerektiğini belirtir. Başka bir ifadeyle kabul edilen tipler kümesi şöyledir:</p>

\[K = \{T \mid T \models Ucan\}\]

<p>Bu kontrol derleme zamanında yapılır. Uçma davranışını sağlamayan bir tipi fonksiyona gönderirsek program henüz çalışmadan anlaşılır bir hata alırız.</p>

<p>Birden fazla koşul da tanımlanabilir:</p>

<div class="language-rust highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">fn</span> <span class="n">raporla</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">nesne</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">T</span><span class="p">)</span>
<span class="k">where</span>
    <span class="n">T</span><span class="p">:</span> <span class="n">Ucan</span> <span class="o">+</span> <span class="nn">std</span><span class="p">::</span><span class="nn">fmt</span><span class="p">::</span><span class="n">Debug</span><span class="p">,</span>
<span class="p">{</span>
    <span class="nd">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span> <span class="n">nesne</span><span class="p">);</span>
    <span class="n">nesne</span><span class="nf">.bilgi_ver</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu fonksiyon, tipin hem <code class="language-plaintext highlighter-rouge">Ucan</code> hem de <code class="language-plaintext highlighter-rouge">Debug</code> davranışlarını sağlamasını ister.</p>

<h2 id="statik-ve-dinamik-çok-biçimlilik">Statik ve dinamik çok biçimlilik</h2>

<p>Trait’ler iki temel biçimde kullanılabilir:</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Yazım</th>
      <th>Özellik</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Statik dispatch</td>
      <td><code class="language-plaintext highlighter-rouge">T: Ucan</code></td>
      <td>Hızlıdır, derleyici tipe özel kod üretir</td>
    </tr>
    <tr>
      <td>Dinamik dispatch</td>
      <td><code class="language-plaintext highlighter-rouge">&amp;dyn Ucan</code></td>
      <td>Farklı tipleri çalışma zamanında birleştirir</td>
    </tr>
  </tbody>
</table>

<p><code class="language-plaintext highlighter-rouge">Vec&lt;Box&lt;dyn Ucan&gt;&gt;</code> kullanarak kuşları, uçakları ve başka uçan tipleri aynı koleksiyonda saklayabiliriz. Bunun küçük bir çalışma zamanı maliyeti vardır; buna karşılık esnek bir mimari sağlar.</p>

<p>Trait’lerin asıl gücü, “Bu nesne hangi sınıftan?” sorusunu geri plana atıp “Bu nesne hangi işleri yapabilir?” sorusunu öne çıkarmasıdır. Sonuçta daha gevşek bağlı, test edilebilir ve genişletilebilir kod elde edilir. Yeni bir tip eklemek için mevcut algoritmaları değiştirmek gerekmez; yalnızca ilgili davranış sözleşmesini uygulamak yeterlidir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Rust" /><category term="Trait" /><category term="Nesne Tabanlı Programlama" /><summary type="html"><![CDATA[Bir uygulamada kuşlar uçar, uçaklar uçar, hatta yeterince kararlı bir geliştiricinin yazdığı kod bile bazen “uçar”. Bu nesneler birbirinden tamamen farklı veri yapılarına sahip olsa da ortak bir davranışı paylaşabilir. Rust’taki trait yapısı, farklı tiplerin sahip olması gereken yetenekleri ortak bir sözleşmeyle tanımlamamızı sağlar. Nesne tabanlı dillerdeki interface kavramına benzese de varsayılan metotlar, generic kısıtları ve güvenli çok biçimlilik gibi güçlü araçlarla daha geniş bir kullanım alanı sunar.]]></summary></entry></feed>