Bölüm 4 — Konu 20: Spread Operatörü (`...`, `...?`) ve Collection If/For
Dizi · 19/64 Dart Türkçe Tutorial
- Bölüm 1 — Konu 1: Dart Nedir, Nerede Kullanılır, Neden Flutter Bu Dili Seçti
- Bölüm 1 — Konu 2: Ortam Kurulumu (Dart SDK, DartPad, Terminal ile Çalıştırma)
- Bölüm 1 — Konu 3: İlk Program (`main()`, `print()`, Dosya Yapısı)
- Bölüm 1 — Konu 4: Yorum Satırları, Temel Sözdizimi Kuralları
- Bölüm 2 — Konu 5: Değişken Tanımlama — `var`, `final`, `const` Farkı
- Bölüm 2 — Konu 6: Temel Tipler — `int`, `double`, `String`, `bool`
- Bölüm 2 — Konu 7: Tip Çıkarımı (Type Inference) ve Açık Tip Belirtme
- Bölüm 2 — Konu 8: `dynamic` ve `Object` — Ne Zaman Kullanılır, Ne Zaman Kaçınılır
- Bölüm 2 — Konu 9: Null Safety Temelleri (`?`, `!`, `late`'e Giriş)
- Bölüm 3 — Konu 10: Aritmetik, Atama, Karşılaştırma, Mantıksal Operatörler
- Bölüm 3 — Konu 11: `if / else if / else`
- Bölüm 3 — Konu 12: `switch` / `switch expression` (Modern Dart)
- Bölüm 3 — Konu 13: Ternary Operatör, `??`, `??=`, `?.`
- Bölüm 3 — Konu 14: `for`, `while`, `do-while` Döngüleri
- Bölüm 4 — Konu 16: `List` — Oluşturma, Erişim, Temel Metodlar
- Bölüm 4 — Konu 17: `Set` — Benzersiz Eleman Mantığı
- Bölüm 4 — Konu 18: `Map` — Key-Value Yapılar
- Bölüm 4 — Konu 19: Koleksiyon Üzerinde `for-in`, `forEach`
- Bölüm 4 — Konu 20: Spread Operatörü (`...`, `...?`) ve Collection If/For
- Bölüm 5 — Konu 21: Fonksiyon Tanımlama, Parametreler (Positional, Named, Optional)
- Bölüm 5 — Konu 22: Varsayılan Parametre Değerleri (Derinlemesine)
- Bölüm 5 — Konu 23: Arrow Function (`=>`) Sözdizimi
- Bölüm 5 — Konu 24: Fonksiyonlar Birinci Sınıf Vatandaş — Değişkene Atama, Parametre Olarak Geçme
- Bölüm 5 — Konu 25: Anonim Fonksiyonlar ve Closure Kavramı (Derinlemesine)
- Bölüm 5 — Konu 26: Recursion (Özyineleme)
- Bölüm 6 — Konu 27: Class Tanımlama, Constructor (Varsayılan, Named, Factory)
- Bölüm 6 — Konu 28: Alanlar (Fields), Metodlar, `this` Kullanımı (Derinlemesine)
- Bölüm 6 — Konu 29: Initializer List, Constructor Kısayolları (Derinlemesine)
- Bölüm 6 — Konu 30: Getter / Setter
- Bölüm 6 — Konu 31: Statik Üyeler (`static`)
- Bölüm 7 — Konu 32: Kalıtım (`extends`), `super` Kullanımı
- Bölüm 7 — Konu 33: Metod Override Etme, `@override`
- Bölüm 7 — Konu 34: Soyut Sınıflar (`abstract class`)
- Bölüm 7 — Konu 35: Interface Mantığı (`implements`)
- Bölüm 7 — Konu 36: Mixin (`with`)
- Bölüm 7 — Konu 37: `enum` — Basit ve Gelişmiş (Metotlu Enum'lar)
- Bölüm 8 — Konu 38: `try / catch / finally`, `throw`
- Bölüm 8 — Konu 39: Özel Exception Sınıfları Yazma
- Bölüm 8 — Konu 40: Sound Null Safety Derinlemesine — `late`, `required`, Non-Nullable Varsayılan Davranış
- Bölüm 8 — Konu 41: `assert` ile Geliştirme Zamanı Kontrolleri
- Bölüm 9 — Konu 42: Generic Sınıflar ve Fonksiyonlar
- Bölüm 9 — Konu 43: Generic Sınırlamalar (`<T extends ...>`)
- Bölüm 9 — Konu 44: Dart'ın Built-in Generic Koleksiyonları Nasıl Çalışır
- Bölüm 10 — Konu 45: `Future` Kavramı, `async`/`await`
- Bölüm 10 — Konu 46: `Future.then`, Hata Yönetimi (`catchError`)
- Bölüm 10 — Konu 47: `Stream` Temelleri, `async*`, `yield`
- Bölüm 10 — Konu 48: `StreamController`, Broadcast Stream
- Bölüm 11 — Konu 49: `map`, `where`, `reduce`, `fold`
- Bölüm 11 — Konu 50: `sort`, Custom Comparator ile Sıralama
- Bölüm 11 — Konu 51: Iterable Kavramı Derinlemesine (Lazy Evaluation)
- Bölüm 11 — Konu 52: Cascade Notasyonu (`..`)
- Bölüm 12 — Konu 53: `pubspec.yaml`, pub.dev'den Paket Ekleme
- Bölüm 12 — Konu 54: Kütüphane Oluşturma, `import`/`export`, `part`/`part of`
- Bölüm 12 — Konu 55: Dart'ta Test Yazımı (`test` Paketi, Unit Test Mantığı)
- Bölüm 12 — Konu 56: Extension Methods
- Bölüm 12 — Konu 57: Dart'ın Derleme Modelleri (JIT vs AOT) ve Bunun Flutter'a Etkisi
- Bölüm 13 — Konu 59: Dart 3 Pattern Matching — Records, Destructuring, Sealed Classes, Exhaustive Switch
- Bölüm 13 — Konu 60: `Never` Tipi, `covariant` ve Generic Variance Detayları
- Bölüm 13 — Konu 61: Event Loop Derinlemesine — Microtask Queue vs Event Queue
- Bölüm 13 — Konu 62: Memory Model & Performans — Garbage Collection, `const` Nesnelerin Bellek Avantajı
- Bölüm 13 — Konu 63: Isolate'ler Arası Mesajlaşmanın Maliyeti ve `compute()`'un İç İşleyişi
- Bölüm 13 — Konu 64: FFI (Foreign Function Interface) — C Koduna Erişim
- Bölüm 13 — Konu 65: Sunucu Tarafında Dart — `dart:io`, `shelf` Paketiyle Basit Bir Backend/CLI Aracı Yazma
- Bölüm 13 — Konu 66: Derleyici & Analiz Araçları — `dart analyze`, Custom Lint Kuralları, `build_runner` Mimarisi
İçindekiler 10 başlık
- Spread Operatörü (...) — Bir Koleksiyonu Diğerinin İçine "Yaymak"
- Aradan Eleman Ekleyerek Kullanma
- ...? — Null-Aware Spread
- Set ve Map'te Spread
- Collection if — Koşullu Eleman Ekleme
- Collection for — Koleksiyondan Koleksiyon Üretme
- Hepsini Bir Arada Kullanmak
- 🎯 Bu Dersten Çıkarılması Gerekenler
- 📝 Ödevler
- 🏁 Bölüm 4 Tamamlandı!
Bölüm 4'ün son konusundayız. Bu konu, Flutter'da widget listeleri oluştururken her gün karşına çıkacak — o yüzden burada sağlam bir temel kurmak gerçekten değerli.
Spread Operatörü (...) — Bir Koleksiyonu Diğerinin İçine "Yaymak"
void main() {
List<int> ilkListe = [1, 2, 3];
List<int> ikinciListe = [4, 5, 6];
List<int> birlesikListe = [...ilkListe, ...ikinciListe];
print(birlesikListe); // [1, 2, 3, 4, 5, 6]
}... (üç nokta), bir koleksiyonun elemanlarını tek tek açıp, bulunduğu yere yerleştirir. ...ilkListe yazdığında, sanki 1, 2, 3 tek tek elle yazılmış gibi davranır.
Spread olmadan aynı işi yapmak isteseydik:
void main() {
List<int> ilkListe = [1, 2, 3];
List<int> ikinciListe = [4, 5, 6];
// Spread olmadan, addAll ile manuel birleştirme
List<int> birlesikListe = [];
birlesikListe.addAll(ilkListe);
birlesikListe.addAll(ikinciListe);
print(birlesikListe); // [1, 2, 3, 4, 5, 6]
}Spread operatörü, bunu tek satırda ve daha okunabilir şekilde yapmanı sağlıyor.
Aradan Eleman Ekleyerek Kullanma
void main() {
List<int> ortaElemanlar = [3, 4, 5];
List<int> tamListe = [1, 2, ...ortaElemanlar, 6, 7];
print(tamListe); // [1, 2, 3, 4, 5, 6, 7]
}Spread'i normal elemanlarla karıştırarak kullanabilirsin — listenin herhangi bir noktasında.
...? — Null-Aware Spread
Eğer yaymak istediğin koleksiyon null olabilir, spread etmeden önce kontrol etmen gerekir. ...? bunu otomatik yapar:
void main() {
List<int>? belkiVarListe; // null
List<int> sonuc = [1, 2, ...?belkiVarListe, 3];
print(sonuc); // [1, 2, 3] — null liste sessizce atlandı, hata vermedi
}Eğer ...? yerine düz ... kullansaydın:
void main() {
List<int>? belkiVarListe;
List<int> sonuc = [1, 2, ...belkiVarListe, 3]; // ❌ HATA! null spread edilemez
}Bu, Bölüm 2-3'te işlediğimiz null safety felsefesinin koleksiyonlara uygulanmış hali — ?. ve ?? gibi, ...? de "bu değer null olabilir, güvenli şekilde ele al" demenin bir yolu.
Set ve Map'te Spread
void main() {
Set<String> setA = {"a", "b"};
Set<String> setB = {"b", "c"};
Set<String> birlesim = {...setA, ...setB};
print(birlesim); // {a, b, c} — Set olduğu için tekrar otomatik silinir
Map<String, int> mapA = {"x": 1, "y": 2};
Map<String, int> mapB = {"z": 3};
Map<String, int> birlesikMap = {...mapA, ...mapB};
print(birlesikMap); // {x: 1, y: 2, z: 3}
}Collection if — Koşullu Eleman Ekleme
Dart, koleksiyon tanımlarken içine doğrudan if yazmana izin verir:
void main() {
bool indirimVarMi = true;
List<String> mesajlar = [
"Hoş geldiniz",
if (indirimVarMi) "Bugüne özel %20 indirim!",
"İyi alışverişler",
];
print(mesajlar);
// [Hoş geldiniz, Bugüne özel %20 indirim!, İyi alışverişler]
}Eğer indirimVarMi false olsaydı, o eleman listeye hiç eklenmezdi — koşullu olarak dahil edilir. Bunu klasik yoldan yapmak isteseydin:
void main() {
bool indirimVarMi = false;
List<String> mesajlar = ["Hoş geldiniz"];
if (indirimVarMi) {
mesajlar.add("Bugüne özel %20 indirim!");
}
mesajlar.add("İyi alışverişler");
print(mesajlar); // [Hoş geldiniz, İyi alışverişler]
}Collection if, bunu çok daha kısa ve tek bir liste tanımı içinde yapmanı sağlıyor. Bu, Flutter'da bir widget listesine koşullu olarak bir widget eklemek istediğinde (örneğin "kullanıcı giriş yapmışsa şu butonu göster") sürekli kullanacağın bir kalıptır.
if-else de kullanılabilir:
void main() {
bool girisYapildi = false;
List<String> menu = [
"Anasayfa",
if (girisYapildi) "Profilim" else "Giriş Yap",
"Ayarlar",
];
print(menu); // [Anasayfa, Giriş Yap, Ayarlar]
}Collection for — Koleksiyondan Koleksiyon Üretme
void main() {
List<int> sayilar = [1, 2, 3, 4];
List<int> kareler = [
for (var sayi in sayilar) sayi * sayi,
];
print(kareler); // [1, 4, 9, 16]
}Bu, aslında Bölüm 11'de göreceğimiz .map() fonksiyonuna çok benzer bir işlevi görür, ama sözdizimi olarak doğrudan koleksiyon tanımının içine gömülüdür. Klasik yoldan yapmak isteseydin:
void main() {
List<int> sayilar = [1, 2, 3, 4];
List<int> kareler = [];
for (var sayi in sayilar) {
kareler.add(sayi * sayi);
}
print(kareler); // [1, 4, 9, 16]
}Collection for, bunu tek satırda ve daha bildirimsel (declarative) bir şekilde ifade etmeni sağlıyor.
Hepsini Bir Arada Kullanmak
void main() {
List<String> vipMusteriler = ["Zeynep", "Can"];
List<String> normalMusteriler = ["Ali", "Veli", "Ayşe"];
bool ozelGunMu = true;
List<String> tumMesajlar = [
"Mağazamıza hoş geldiniz",
if (ozelGunMu) "Bugün özel gün, indirimler geçerli!",
for (var musteri in vipMusteriler) "VIP: $musteri, size özel fırsatlar var",
...normalMusteriler.map((m) => "Merhaba $m"),
];
tumMesajlar.forEach(print);
}Bu örnek biraz ileri seviye görünebilir (.map() henüz işlemedik) ama amacım şu: spread, collection if ve collection for'un hepsi bir arada kullanılabilir, ve bu, Flutter'da bir widget ağacı (örneğin bir Column'un children listesi) oluştururken sürekli karşına çıkacak bir kalıptır — koşullu widget'lar, bir listeden üretilen widget'lar, sabit widget'lar hepsi aynı liste tanımında bir arada bulunur.
🎯 Bu Dersten Çıkarılması Gerekenler
...: bir koleksiyonun elemanlarını başka bir koleksiyonun içine "yayar" (açar)....?: null olabilecek koleksiyonları güvenli şekilde yayar, null ise atlar.- Collection
if: bir koşula göre bir elemanı koleksiyona dahil edip etmemeyi sağlar (if-elsede desteklenir). - Collection
for: bir koleksiyondan yeni bir koleksiyon üretmeyi, ayrı bir döngü yazmadan, doğrudan tanım içinde yapmayı sağlar. - Bu üç özellik birlikte kullanılabilir — Flutter'da widget listeleri oluştururken çok sık karşına çıkacak.
📝 Ödevler
- [ ] İki ayrı listeyi spread operatörü ile birleştirip yeni bir liste oluştur.
- [ ] Nullable bir listeyle
...?kullanarak, liste null olduğunda hata almadan başka bir listeye dahil et. - [ ] Bir kullanıcının "premium üye" olup olmamasına göre collection
ifile bir menü listesine koşullu eleman ekle. - [ ] Bir sayı listesinden, collection
forkullanarak her sayının iki katını içeren yeni bir liste üret. - [ ] Spread, collection if ve collection for'u aynı liste tanımında birlikte kullanan bir örnek yaz (örn. sabit elemanlar + koşullu eleman + bir listeden türetilmiş elemanlar).
🏁 Bölüm 4 Tamamlandı!
Artık List, Set, Map koleksiyonlarını oluşturabiliyor, üzerlerinde gezinebiliyor ve spread/collection if/for ile bunları esnek şekilde birleştirebiliyorsun. Bu, Flutter'da widget ağaçları kurarken en çok kullanacağın becerilerden biri olacak.
Sıradaki durak Bölüm 5 — Fonksiyonlar: parametreler, arrow function sözdizimi, closure kavramı ve fonksiyonların Dart'ta "birinci sınıf vatandaş" olması gibi konularla devam edeceğiz.