↑↓ seç · Enter aç · Esc kapat

Mutlu Tekin
Mutlu Tekin
← Yazılar

Bölüm 4 — Konu 20: Spread Operatörü (`...`, `...?`) ve Collection If/For

3 dk okuma #dart
Dizi · 19/64 Dart Türkçe Tutorial
  1. Bölüm 1 — Konu 1: Dart Nedir, Nerede Kullanılır, Neden Flutter Bu Dili Seçti
  2. Bölüm 1 — Konu 2: Ortam Kurulumu (Dart SDK, DartPad, Terminal ile Çalıştırma)
  3. Bölüm 1 — Konu 3: İlk Program (`main()`, `print()`, Dosya Yapısı)
  4. Bölüm 1 — Konu 4: Yorum Satırları, Temel Sözdizimi Kuralları
  5. Bölüm 2 — Konu 5: Değişken Tanımlama — `var`, `final`, `const` Farkı
  6. Bölüm 2 — Konu 6: Temel Tipler — `int`, `double`, `String`, `bool`
  7. Bölüm 2 — Konu 7: Tip Çıkarımı (Type Inference) ve Açık Tip Belirtme
  8. Bölüm 2 — Konu 8: `dynamic` ve `Object` — Ne Zaman Kullanılır, Ne Zaman Kaçınılır
  9. Bölüm 2 — Konu 9: Null Safety Temelleri (`?`, `!`, `late`'e Giriş)
  10. Bölüm 3 — Konu 10: Aritmetik, Atama, Karşılaştırma, Mantıksal Operatörler
  11. Bölüm 3 — Konu 11: `if / else if / else`
  12. Bölüm 3 — Konu 12: `switch` / `switch expression` (Modern Dart)
  13. Bölüm 3 — Konu 13: Ternary Operatör, `??`, `??=`, `?.`
  14. Bölüm 3 — Konu 14: `for`, `while`, `do-while` Döngüleri
  15. Bölüm 4 — Konu 16: `List` — Oluşturma, Erişim, Temel Metodlar
  16. Bölüm 4 — Konu 17: `Set` — Benzersiz Eleman Mantığı
  17. Bölüm 4 — Konu 18: `Map` — Key-Value Yapılar
  18. Bölüm 4 — Konu 19: Koleksiyon Üzerinde `for-in`, `forEach`
  19. Bölüm 4 — Konu 20: Spread Operatörü (`...`, `...?`) ve Collection If/For
  20. Bölüm 5 — Konu 21: Fonksiyon Tanımlama, Parametreler (Positional, Named, Optional)
  21. Bölüm 5 — Konu 22: Varsayılan Parametre Değerleri (Derinlemesine)
  22. Bölüm 5 — Konu 23: Arrow Function (`=>`) Sözdizimi
  23. Bölüm 5 — Konu 24: Fonksiyonlar Birinci Sınıf Vatandaş — Değişkene Atama, Parametre Olarak Geçme
  24. Bölüm 5 — Konu 25: Anonim Fonksiyonlar ve Closure Kavramı (Derinlemesine)
  25. Bölüm 5 — Konu 26: Recursion (Özyineleme)
  26. Bölüm 6 — Konu 27: Class Tanımlama, Constructor (Varsayılan, Named, Factory)
  27. Bölüm 6 — Konu 28: Alanlar (Fields), Metodlar, `this` Kullanımı (Derinlemesine)
  28. Bölüm 6 — Konu 29: Initializer List, Constructor Kısayolları (Derinlemesine)
  29. Bölüm 6 — Konu 30: Getter / Setter
  30. Bölüm 6 — Konu 31: Statik Üyeler (`static`)
  31. Bölüm 7 — Konu 32: Kalıtım (`extends`), `super` Kullanımı
  32. Bölüm 7 — Konu 33: Metod Override Etme, `@override`
  33. Bölüm 7 — Konu 34: Soyut Sınıflar (`abstract class`)
  34. Bölüm 7 — Konu 35: Interface Mantığı (`implements`)
  35. Bölüm 7 — Konu 36: Mixin (`with`)
  36. Bölüm 7 — Konu 37: `enum` — Basit ve Gelişmiş (Metotlu Enum'lar)
  37. Bölüm 8 — Konu 38: `try / catch / finally`, `throw`
  38. Bölüm 8 — Konu 39: Özel Exception Sınıfları Yazma
  39. Bölüm 8 — Konu 40: Sound Null Safety Derinlemesine — `late`, `required`, Non-Nullable Varsayılan Davranış
  40. Bölüm 8 — Konu 41: `assert` ile Geliştirme Zamanı Kontrolleri
  41. Bölüm 9 — Konu 42: Generic Sınıflar ve Fonksiyonlar
  42. Bölüm 9 — Konu 43: Generic Sınırlamalar (`<T extends ...>`)
  43. Bölüm 9 — Konu 44: Dart'ın Built-in Generic Koleksiyonları Nasıl Çalışır
  44. Bölüm 10 — Konu 45: `Future` Kavramı, `async`/`await`
  45. Bölüm 10 — Konu 46: `Future.then`, Hata Yönetimi (`catchError`)
  46. Bölüm 10 — Konu 47: `Stream` Temelleri, `async*`, `yield`
  47. Bölüm 10 — Konu 48: `StreamController`, Broadcast Stream
  48. Bölüm 11 — Konu 49: `map`, `where`, `reduce`, `fold`
  49. Bölüm 11 — Konu 50: `sort`, Custom Comparator ile Sıralama
  50. Bölüm 11 — Konu 51: Iterable Kavramı Derinlemesine (Lazy Evaluation)
  51. Bölüm 11 — Konu 52: Cascade Notasyonu (`..`)
  52. Bölüm 12 — Konu 53: `pubspec.yaml`, pub.dev'den Paket Ekleme
  53. Bölüm 12 — Konu 54: Kütüphane Oluşturma, `import`/`export`, `part`/`part of`
  54. Bölüm 12 — Konu 55: Dart'ta Test Yazımı (`test` Paketi, Unit Test Mantığı)
  55. Bölüm 12 — Konu 56: Extension Methods
  56. Bölüm 12 — Konu 57: Dart'ın Derleme Modelleri (JIT vs AOT) ve Bunun Flutter'a Etkisi
  57. Bölüm 13 — Konu 59: Dart 3 Pattern Matching — Records, Destructuring, Sealed Classes, Exhaustive Switch
  58. Bölüm 13 — Konu 60: `Never` Tipi, `covariant` ve Generic Variance Detayları
  59. Bölüm 13 — Konu 61: Event Loop Derinlemesine — Microtask Queue vs Event Queue
  60. Bölüm 13 — Konu 62: Memory Model & Performans — Garbage Collection, `const` Nesnelerin Bellek Avantajı
  61. Bölüm 13 — Konu 63: Isolate'ler Arası Mesajlaşmanın Maliyeti ve `compute()`'un İç İşleyişi
  62. Bölüm 13 — Konu 64: FFI (Foreign Function Interface) — C Koduna Erişim
  63. Bölüm 13 — Konu 65: Sunucu Tarafında Dart — `dart:io`, `shelf` Paketiyle Basit Bir Backend/CLI Aracı Yazma
  64. Bölüm 13 — Konu 66: Derleyici & Analiz Araçları — `dart analyze`, Custom Lint Kuralları, `build_runner` Mimarisi
Dizinin sayfası →
İçindekiler 10 başlık
  1. Spread Operatörü (...) — Bir Koleksiyonu Diğerinin İçine "Yaymak"
  2. Aradan Eleman Ekleyerek Kullanma
  3. ...? — Null-Aware Spread
  4. Set ve Map'te Spread
  5. Collection if — Koşullu Eleman Ekleme
  6. Collection for — Koleksiyondan Koleksiyon Üretme
  7. Hepsini Bir Arada Kullanmak
  8. 🎯 Bu Dersten Çıkarılması Gerekenler
  9. 📝 Ödevler
  10. 🏁 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"

dart
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:

dart
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

dart
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:

dart
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:

dart
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

dart
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:

dart
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:

dart
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:

dart
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

dart
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:

dart
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

dart
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-else de 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 if ile bir menü listesine koşullu eleman ekle.
  • [ ] Bir sayı listesinden, collection for kullanarak 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.