Dart Programlama Dili: Hızlı Başlangıç Kılavuzu

Dart programlama diline hızlı bir başlangıç yapmak isterseniz, bu dökümandan faydalanabilirsiniz. Dart programlama dilini öğrenmek isteyenler veya Flutter programlama diline başlamadan önce Dart altyapısı oluşturmak isteyenler için bu dökümandaki müfredatı takip etmek faydalı olacaktır.

1. Dart Programlama Dili Hakkında Genel Bilgiler

Dart 1.0 versiyonu aynı üniversiteden mezun iki arkadaş olan Lars Bak ve Kasper Lund tarafından 2013 yılı Kasım ayında oluşturuldu ve Dart programlama dili modern web uygulamaları ve mobil uygulamalar geliştirmenizi kolaylaştırmayı hedeflemiştir. Javascript’i temel alır, nesne yönelimli ve bileşen tabanlıdır. Dart programlama dilinde bütün bileşenler bir nesne olarak tanımlanır.

Flutter + Dart = ?

Flutter kullanıcıları tarafından geliştirilmeye açık bir yapıdır. Kullanıcı arayüzleri oluşturmayı daha keyifli hale getiren widget mimarisi sayesinde geliştiricilerin dikkatini çekmeyi başararak çok kısa sürede çok hızlı bir yükseliş sağlamıştır.

Tüm platformlarda çok hızlı bir geliştirme ve çalıştırma deneyimi sunan Dart dilini şimdi daha yakından tanıyalım. Kodlarınızı çalıştırmak için DartPad.dev adresini kullanabilirsiniz.

Başlangıç Fonksiyonu: Main()

Her uygulamanın bir giriş noktası vardır. Dart dilinde uygulamalar main() metodu ile başlatılır. Eğer uygulamanızda main fonksiyonu yok ise uygulamanızın başlaması imkansızdır. Kodumuz süslü parantez olarak tabir edilen alan içerisinde yazılmaktadır.

main() {
 // kodlama alanı
}

2. Değişkenler ve Veri Tipleri

Merhaba Dünya!

Yeni bir programlama dili öğrenirken genellikle ekrana veya konsola yazdırdığımız çıktıyı yazdıralım. Print() fonksiyonu ile konsola “Merhaba Dünya!” çıktısını gönderin.

main() {
  print('Merhaba Dünya!');
}

Uygulamamızın giriş fonksiyonu olan main() metodunu anladık. Bunun içerisinde yer alan print fonksiyonu konsola bir çıktı göndermemizi sağlar. Ve satırın sonundaki noktalı virgül (;) ifadesini görmüşsünüzdür. Bu ifade bir çok programlama dilinde olduğu gibi yazdığımız kodun daha sağlıklı çalışabilmesi için kod parçacıklarının, ifadelerin sonuna yerleştirilir.

Bu kod parçacığında sadece bir metin çıktısı aldık. Ancak çoğu durumda kullanıcıdan alacağımız verilerle işlem yaparız. Aslında buna ihtiyaç duymasaydık, programlama teknolojilerinin daha fazla gelişmesine uzun yıllar ihtiyaç duyuyor olmazdık.

Yorum Satırları

Yorum satırları yalnızca geliştiriciler tarafından proje dosyaları içerisinde görüntülenebilir. Program tarafından yorumlanmaz ve çalıştırılamaz. İçerisinde istediğiniz ifadeyi bulundurabilir ve notlarınızı alabilirsiniz.

Tek satır ve çok satırlı yorum satırları için aşağıdaki gibi bir kullanım uygundur. ( // ve /* … */ şeklinde )

/*
Bu yorum metni birden fazla satırda kullanım içindir.
Başlangıç ve bitişi gördüğünüz gibidir.
*/

void main(){
  // Tek satırlık kullanım bu şekildedir.
}

Değişkenler ve Sabitler

Değişkenler daha sonra kullanabilmek için veri veya veri setlerini isimlendirerek veya numaralandırarak tanımlayıp geçici olarak saklayabildiğimiz yapılardır. Değişken adı ve sonrasında eşittir (=) ifadesi kullanılarak değeri verilir.

Değişkenlere isim verirken programlama dünyasında lowCamelCase olarak adlandırılan yapıyı kullanmamız tavsiye edilir. Bu yapıda sadece ilk kelimenin baş harfi küçük, diğer kelimelerin baş harfleri büyük olarak kullanılır.

Ayrıca değişken isimlerinde Türkçe karakterler kullanmanız tavsiye edilmez. Dart için çoğu zaman değişken tiplerini açıklamanıza gerek kalmaz. Ancak saklanacak veri tipinin değişkene bildirilmesi daha avantajlı olacaktır.

main() {
  int benimSayisalDegiskenim = 5;
}

Yukarıdaki örnekte sayısal bir değişken oluşturduk, ismi benimSayisalDegiskenim ve değeri 5 olarak tanımlandı. Değişken adından önceki kısım (int deyimi) değişkenimizin Integer yani sayısal olduğunu ifade eder.

ÖNEMLİ BİLGİ
Değişken tipi belirtmek istemiyorsanız, değişkeninizin alacağı değere göre otomatik olarak tipini belirlemek istiyorsanız, değişken tipi yerine var ifadesini kullanmanız gerekmektedir.

Değişkeni Yazdırma

Oluşturduğumuz değişkenle çeşitli hesaplamalar, işlemler yapabiliriz. Şimdilik bu değişkenin değerini çıktı alacağız.

main() {
  int benimSayisalDegiskenim = 5;
  print(benimSayisalDegiskenim); // Konsol çıktısı "5" olarak görünecektir.
}

Veri Tipleri

Dart dilinde değişken veya diğer veri saklama yapıları için çeşitli veri tipleri ve bu tiplere ait çeşitli özellikler bulunmaktadır.

En çok kullanacağımız veri tipleri Numbers, Strings ve Booleans olacaktır. Bunun dışında diğer programlama dillerinde array olarak karşınıza çıkacak olan, Lists yapısı da oldukça fazla kullanılan bir yapıdır. Tüm türleri sırası ile inceleyip örnekler yapacağız.

Anlayamadığınız kısımları daha detaylı açıklayabilmem adına yazının sonundaki form üzerinden sorularınızı ve eleştirilerinizi iletebilirsiniz.

Bir değişken tanımlaması yaptığınızda değer atması yapılmazsa, değişken null olarak değer alır. Bunun nedeni değişkenlerin de Dart dilinde nesne olarak kabul edilmesidir.

Dart dilinde değişkenlerin veya sabitlerin de bir nesne olduğunu unutmayın. Sıkça kullanacağımız nesne veri tipleri aşağıdaki gibidir.

  • Sayısal (intdouble)
  • Metinsel (String)
  • Boolean (bool)
  • Liste (List) (Array Yapısı)
  • Koleksiyon (Set)
  • Map (Map)
  • Semboller (Symbol)

Değişkenlerde Veri Tipleri

Integer ve Double veri tipleri, sayısal değerler için en çok kullanılan veri tipleridir. Int ve Double anahtar kelimeleri ile tanımlanır. String ifadeler için tek veya çift tırnak kullanılabilmektedir.

main() {
   var isim = 'Mehmet Ali VATANLAR'; // String olarak tanımlanır.
   String dogumYeri = "Rize"; // String olarak tanımlanır.
   var dogumTarihi = 1992; // Integer olarak tanımlanır.
   var kilo = 82; // Integer olarak tanımlanır.
   var boy = 1.75; // Double olarak tanımlanır.

   var programlamaDilleri = ['SwiftUI', 'JS'];
   var dosyalar = {
     'tags': ['vesikalik'],
     'url': '//path/to/ben.jpg'
   };
 }

Değişken türü belirtmediğinizde Dart sizin için değişken türünü tespit ederek tanımlayacaktır. Ancak değişken içeriği değişme potansiyeli var ise, Dynamic veya Object tanımlaması yapmanız gerekir.

Veri Birleştirme

Verileri veya değişkenleri birleştirmek için aşağıdaki kullanım şekilleri uygundur. Javascript’de yaptığımız gibi (+) artı ifadesi ile metinsel verileri birleştirebilmekteyiz. Sayısal ifadeler için ise aynı ifade toplama işleminde kullanılmaktadır.

main() {
   String s1 = "Mehmet Ali";
   String s2 = "VATANLAR";
   print(s1 + s2); // Mehmet AliVATANLAR çıktısını verir.
   print(s1 + " " + s2); // Mehmet Ali VATANLAR çıktısını verir.
 }

Örnekte görüldüğü gibi 2 değişkenin arasına string bir ifade yerleştirebildik. Aynı şekilde string içerisine bir değişken yerleştirmek isteseydik aşağıdaki örneklerde olduğu gibi de kullanabilirdik.

main() {
  String s1 = "Mehmet Ali";
  String s2 = "VATANLAR";
  print("Merhaba, benim adım " + s1 + " soyadım ise $s2. ${20+9} yaşındayım.");
}

Yukarıda string ifadelerin içerisine değişken yerleştirebilmenin 2 farklı yolunu görebiliyorsunuz. Ve alttaki örnekte de multiline örnekleri inceleyebilirsiniz. Satırların sonunda ( + ) veya ( , ) ifadelerinin olmadığını görebileceksiniz. Yalnızca değişken ile birleştirme yaparken (+) ifadesi kullanılmış. Birden fazla satırın yorumlanıp tek satırda çıktı vermesini istiyorsak aşağıdaki gibi kullanabiliriz.

main() {
  String cevap = "Evet";
  var s1 = "Merhaba, "
          "String ifadeler için"
          " "
          "Birden fazla satır kullanımı bu şekilde mi? " +
      cevap;
  print(s1);
}

Ancak birden fazla satırın yorumlanarak, birden fazla satırda çıktı vermesini istiyorsak (“””) şeklinde 3 adet çift tırnakla kullanabilmekteyiz.

main() {
   var satirliString = """Merhaba,
Günün nasıl geçiyor?
Umarım her şey yolundadır.""";

print(satirliString);
}

Bu durumda çıktının böldüğümüz her satırın konsolda da yeni bir satıra denk düştüğünü göreceksiniz.

Sabitler (Final ve Const)

Final ve Const deyimleri sabit değişkenler tanımlamak için kullanılır.

COMPILE TIME VE RUNTIME
Derleme zamanı (Compile Time) kodumuzun makine diline dönüştürülme işlemine kadar geçen süreyi ifade eder. Çalışma süresi (Runtime) ise, kodumuzun programın içerisinde yazdığımız bölümün çalışması anlamına gelir.

Final değişkenler compile-time veya runtime sırasında sabit değerler alırlar. Const değişkenler ise yalnızca derleme zamanında değer alır. Derleme tamamlandıktan sonra veri ataması yapılamaz.

Örnek olarak, kullanıcıdan alacağınız bir veriyi const değişkene değil final değişkene almanız gerekir.

final name = 'Bob';
final String nickname = 'Bobby';

Const değişkenler compile-time değer alırlar. Örn: const dogumGunu = getDogumGunuDB() değeri atanır sonra değiştirilemez.

const Object i = 3;
const list = [i as int];
const map = {if (i is int) i: 'int'}; 
const set = {if (list is List<int>) ...list}; 

Tür Çıkarımı (Type Inference)

Dart programlama dili çok güçlü bir yapıda kodlanmıştır. Bu şekilde kodlanan programlama dillerinde bir değişkenin değerinin tipiyle her zaman eşlemesini sağlamak adına tip tanımlamasını zorunlu tutar. Ancak Dart Programlama dilinde tür çıkarımı yapılabildiği için, değişkenin türünü belirlemeniz zorunlu tutulmamıştır.

Değişken tanımlaması yapılırken başlangıç değeri var ise, değişkenin türü bu değere göre belirlenir. Sonrasında runtimeType metodu ile değişkenin tipini öğrenebiliriz.

main() {
  var bookTitle = "Kuran-i Kerim";
  var bookPageCount = 600;
  print(bookTitle.runtimeType); // String çıktısını verir.
  print(bookPageCount.runtimeType); // int çıktısını verir. 
}

Dinamik Değişkenler

Bir değişkenin birden fazla tipte değer tanımlamanız gerekirse kullanabileceğiniz yapılardır. Geçici verilerin, geçici kullanım durumları için kullanılabilir.

main() {
  dynamic dinamikDegisken = 'Metinsel değer :)'; // String
  print(dinamikDegisken);
  print(dinamikDegisken.runtimeType); 

  dinamikDegisken = 5; // int 
  print(dinamikDegisken);
  print(dinamikDegisken.runtimeType);
 
  dinamikDegisken = true; // bool
  print(dinamikDegisken);
  print(dinamikDegisken.runtimeType); 
}

3. Operatörler

Dart programlama dilinde operatörleri inceliyoruz. Operatörler verileri değiştirmek, işlemek veya çeşitli işlemler yapmak için kullanılan ifadelerdir.

  • Aritmetik operatörler
  • Eşitlik ve İlişkisel Operatörler
  • Tip Test Operatörleri
  • Atama Operatörleri
  • Mantıksal operatörler

Operatörler kendi arasında öncelik sırasına sahiptirler. Operatör öncelikleri burada verilen tablodaki sıralamaya göre yukarıdan aşağıya doğru önceliklidir.

Aritmetik Operatörler

Aritmetik operatörler ile toplama, çıkarma, çarpma ve bölme işlemleri yapılabildiği gibi, bölümden kalan, arttırma, azaltma gibi işlemler de yapılabilmektedir. Aşağıdaki örnekleri inceleyebilirsiniz.

main(){
   int sayi1 = 20;
   int sayi2 = 15;

   // 4 İşlem
   print(sayi1 + sayi2); // Toplama
   print(sayi1 - sayi2); // Çıkarma
   print(sayi1 / sayi2); // Bölme
   print(sayi1 * sayi2); // Çarpma

   // Diğerleri
   print(- sayi1); // Değeri negatife çevirir.
   print(sayi1 ~/ sayi2); // Bölme işleminden tam sayı döndürür. 
   print(sayi1 % sayi2); // Bölme işleminden kalan.

   // Arttırma ve Azaltma
   sayi1++; // sayi1 = sayi1 + 1;
   ++sayi1; // sayi1 = sayi1 + 1;
   sayi2--; // sayi2 = sayi2 -1;
   --sayi2; // sayi2 = sayi2 - 1; 

   print(sayi1++); // Önce değişkeni yazdırır sonra +1 ekler.
 }

Eşitlik Kontrolleri ve İlişkisel Operatörler

Bu operatörler ise bir değerin diğeri ile büyüklüğünü, küçüklüğünü, eşitliğini veya eşitsizliğini kontrol eder. Karşılaştırma operatörleri olarak da adlandırabiliriz. Ayrıca bu operatörlerin döndürdüğü sonuç daima Boolean türündedir. Yani alacağımız cevap daima Evet/Hayır seçeneklerinden birisi olacaktır.

GENEL BİLGİ
Eşitlik operatörleri yalnızca sayısal ifadelerde kullanılmaz. Metinsel ifadelerin eşitliği de kontrol edilebilir.

main(){
   int sayi1 = 20;
   int sayi2 = 15;

   print(sayi1 > sayi2); // sayi1 sayi2'den büyüktür. TRUE
   print(sayi1 < sayi1); // sayi1 sayi2'den küçüktür. FALSE
   print(sayi1 == sayi2); // sayi1 ve sayi2 eşittir. FALSE
   print(sayi1 != sayi2); // sayi1 ve sayi2 eşit değildir. TRUE
}

Tip Test Operatörleri

Tip test operatörleri ile değişkenlerin veya diğer tanımlı verilerin tür kontrolünü gerçekleştirebilirsiniz. Örneğin bir değişken tanımladınız, bu değişken ile yapacağınız bir işlem öncesinde değerinin sayısal olup olmadığını kontrol etmek istiyorsunuz. Bu aşamada tip test operatörlerini kullanabilirsiniz.

main(){
   int sayi1 = 20;
   int sayi2 = 15;
   String metn1 = "Merhaba!";

   print(sayi1 is int); // True
   print(sayi2 is int); // True 
   print(metn1 is String); // True
   print(metn1 is double); // False
   print(metn1 is bool); // False
}

Bileşik Atama Operatörleri

Bileşik atama operatörleri ise “a = a + b” gibi desenleri daha kısa ve okunaklı bir hale getirmemizi sağlar. Bunun yerine “a += b” ifadesini kullandığımızda, a ile b değişken değerlerinin toplamını a değişkenine atamış oluruz. Bileşik atama operatörleri aşağıdaki gibidir.

Operatorİşlem
a –= ba = a – b
a /= ba = a / b
a %= ba = a % b
a »= ba = a » b
a ^= ba = a ^ b
a += ba = a + b
a *= ba = a * b
a ~/= ba = a ~/ b
a «= ba = a « b
a &= ba = a & b
a |= ba = a | b

Mantıksal Operatörler

Bu operatörler ile ve, veya gibi sorguların mantıksal olarak sonuçlandırılmasını sağlar.
Örneğin; Maç saat 2 de ise gelirim, 3 de ise de gelirim ama 3’den sonra gelemem.

Operatörisimkullanın
!DEĞİLİşlenen değerin durumunu tersine çevirir. a = true ise; !a false sonucunu verir.
||VEYAİki işlenenden herhangi biri yanlış değilse, sonuç doğrudur.
&&VEHer iki işlenen de yanlış değilse, sonuç doğrudur.
main() {
  var A = true;
  var B = false;
  var expr = A && B; // false

  print(!A); // !true --> false
  print(!B); // !false --> true
  print(true || expr); // true || expr --> true
  print(false || expr); // false || expr --> expr
  print(true && expr); // true && expr --> expr
  print(false && expr); // false && expr --> false
}

Birden çok operatörü aynı sorguda kullanabilirsiniz. Örneğin bir değişkene A ve B değişken değerleri ile ilgili şöyle bir işlem sonucunu aktarabilirsiniz; ” A || 15 > C “, bu durumda A değerinin TRUE, 15 değerinin de C’den büyük olması şartlarından birisi bu sorgunun TRUE döndürmesi için yeterlidir.
Arada && kullanılmış olsaydı, iki koşulun da true dönmesi gerekirdi.

Koleksiyonlar (List, Set ve Map)

İskambil kağıtlarından oluşan bir deste düşünün. Bu kart destesi bir kart koleksiyonu olarak kabul edilebilir. Dart programlarken kullanacağımız koleksiyonlar da buna benzer veri desteleridir. Fakat farklı yapılarda koleksiyon tipleri mevcuttur. Verileri gruplama yöntemi ve diğer özelliklere bağlı olarak 3 farklı koleksiyon tipini inceleyeceğiz.

Koleksiyonlar diğer programlama dillerinde karşımıza diziler olarak gelmektedir. Diğer programlama dillerinin aksine Dart, geniş özellikleri olan bir koleksiyon yapısı yerine, ihtiyaçlarınıza göre kullanabileceğiniz 3 farklı yapıya sahiptir.

Koleksiyonlar da değişkenler ve diğer nesnelerde olduğu gibi isimlendirilmelidir.

List (Sıralı Veri Koleksiyonu)

Bu yapı sıralı bir koleksiyondur. Listelerin içerisindeki elemanların index (sıra) numarası vardır ve elemanlar bu sıra numaralarına göre çağrılabilir. Bu değerler (indeks) 0’dan başlar. İlk sıradaki liste elemanı 0 indeksine sahiptir.

main() {
  var ornekListe = [1,2,3];
  print(ornekListe);

  var ornekListe2 = ["Mehmet Ali VATANLAR", "29", "İstanbul Aydın Üniversitesi"];
  print(ornekListe);
}

List Veri Tipleri

Tanımladığımız ilk liste sadece sayılardan oluşurken, ikinci listede metinsel ifadelerin de olduğunu görüyorsunuz. Bu durumda bu durumda, bu liste örnekleri için runtimeType metodu ile tür çıkarımı yapacak olursak alacağımız yanıt ilk örnek için JSArray<int> olurken, ikinci örnek için JSArray<Object> olacaktır.

Sadece metinsel ifadelerden oluşan bir liste oluşturmuş olsaydık da JSArray<String> şeklinde dönüş alıyor olacaktık.

List Oluşturma

main() {
   var yeniListem = List();
   print(yeniListem);
}

Yukarıdaki örnekte yalnızca bir liste oluşturma işlemi yapılıyor. Liste hiç bir değer olmadan sadece yeniListem ismi ile oluşturulmuş oluyor. Çıktı almak istediğimizde ise boş bir küme “[]” şeklinde köşeli parantezler ile sonuç alırız.

Belirli bir türde boş bir liste oluşturmak istersek de aşağıdaki gibi tanımlamamız gerekmektedir. Sonraki satırda da String olup olmadığını kontrol ediyoruz.

main() {
   var meyveListesi = List<String>();
   print(meyveListesi is List<String>);
}

Burada farklı olarak List ifadesini kullanırken parantezlerin öncesinde <String> ile bu dizinin String değerler alacağını belirttik. Bu kontrol çıktısının sonucu TRUE olacaktır.

List Elemanına Erişim

Elemanlara erişim sağlarken indekslerimiz 0’dan başlıyor demiştik. Yani listede 1. elemanın indeksi 0’dır. Yani erişmek istediğiniz elemanın sırasının (-1) bir eksiği, aynı elemanın indeks değerini belirtecektir.

main() {
  var sebzeListesi = ['Patates', 'Biber', 'Salatalık'];
  print(sebzeListesi[1]);
}

Yukarıdaki örnekte gördüğünüz gibi sebzeListesi[1] elemanını çağırıp print ettik. Fakat gelecek olan değer 2. numaralı eleman olacaktır. Yani bu kod çalıştığında Biber çıktısını verecektir.

LİSTEDEKİ ELEMAN SAYISI
Bir listedeki eleman sayısını bulmak için listeAdi.length değerini alabilirsiniz. Böylelikle örneğin son elemanın indeksini öğrenmek için listeAdi.length-1 ile son elemanı çağırabilirsiniz.

Yeni List Değeri Ekleme

List bileşenine yeni bir değer eklemek için .add() metodunu kullanacağız. Bu yalnızca bir eleman eklememizi sağlar. Daha fazla eleman eklemek istediğimizde de .addAll() metodu kullanılır. Bu iki metod için de parametre göndermemiz gerekir. İkinci metodumuz için ekleyeceğimiz elemanları liste halinde göndermemiz gerekmektedir.

main() {
   var kisiListesi = ['Mehmet Ali', 'Şafak', 'Doğukan'];
   kisiListesi.add('Eda');
   print(kisiListesi); 
}

Tek bir eleman eklerken bu şekilde işlemimizi tamamlayabiliyoruz. Eklediğimiz değeri bir değişkene tanımlayarak veya bir listenin içindeki bir elemanı alarak yapabilirdik. Aynı şekilde birden fazla ekleme yaparken farklı bir listeyi de başka bir listenin içine ekleyebilmekteyiz. Şimdi .addAll() metodunu inceleyelim.

main() {
   var kisiListesi = ['Mehmet Ali', 'Şafak', 'Doğukan', 'Ahmet'];
   kisiListesi.addAll(['Burak', 'Melih']); 

   var gecGelenler = ['Dilara', 'Merve'];
   kisiListesi.addAll(gecGelenler);
   print(kisiListesi);
}

Bu örnekte de gördüğünüz gibi liste tanımlanırken 4 kişiden oluşuyor. Sonrasında addAll() fonksiyonu ile 2 kişi daha ekleniyor. Sonraki aşamada ise ekleyeceğimiz 2 kişi daha var ve bu kişiler bir liste olarak tanımlanıyor. Bu durumda bir önceki satırlarda olduğu gibi köşeli parantez ( [] ) kullanmamıza gerek kalmıyor. Çünkü zaten eklemek için tanımladığımız bileşen bir liste olarak tanımlandı.

List Elemanlarını Silme

Bir liste elemanını silerken indeks değerinden faydalanıyoruz. Tek bir öğeyi silmek için .removeAt(); metodu ile tamamlayabiliriz.

benimListem.removeAt(0);

List içerisindeki elemanların tümünü silmek istersek de .clear(); fonksiyonunu kullanabiliriz.

benimListem.clear();

List Elemanları için Map Metodu

Bu metod bir koleksiyon türü olan map ile karıştırılmamalıdır. Bu metod yardımı ile diğer programlama dillerinde dizi (array) elemanlarını listelerken hazırlayacağımız bir döngü gibi bir yapı mevcuttur. List içindeki elemanların herbirini bir değere atar ve bu değerle işlemler yapmamıza yardımcı olur.

main() {
   var kisiListesi = ['Ayşe', 'Ahmet', 'Burak'];
   var mapKisiListesi = kisiListesi.map((kisiAdi) => 'Merhaba $kisiAdi').toList();
   print(mapKisiListesi);
}

Bu örneği çalıştırdığımızda alacağımız sonuç, List türünde olacaktır ve değeri [Merhaba Ayşe, Merhaba Ahmet, Merhaba Burak] olur. Liste olmasını sağlayan fonksiyonumuz ise .toList() metodudur. Eğer .toList() metodunu kullanmamış olsaydık, mapKisiListesi’nin runtimeType dönüşü MappedListIterable<String, String> olacaktı.

Bir örnek daha yapalım. Bu örnekte, list türünde verilen 3 sayının 2 katı ile yeni bir list oluşturalım.

main() {
   var integers = [1,2,3];
   var katlari = integers.map((sayi) => sayi*2).toList();
   print(katlari);
}

Set (Sırasız Veri Koleksiyonu)

Listeler de tıpkı List bileşeni gibi verileri belirli bir düzende saklamak için kullanılır. Set tanımlaması yaparken köşeli parantez yerine süslü parantez kullanılır.

main() {
  var setOrnegi = {1,2,3};
  print(setOrnegi);
}

Set tanımlaması yaparken, değer türünü de belirtmek isterseniz aşağıdaki gibi bir kullanım gerçekleştirebilirsiniz.

main() {
  var numaralar = <num>{1,1.5,2,2.5};
  print(numaralar);
}

2 farklı şekilde bir Set koleksiyonu oluşturabilirsiniz. Aşağıda gördüğünüz 2 örnek de kullanım için uygundur. Bu aşamada tercih sizin kodlama alışkanlıklarınıza kalmış.

main() {
   var kisiler = <String>{};
   print(kisiler);

   Set<String> kisilerDiger = {};
   print(kisilerDiger);
}

KOLEKSİYON FONKSİYONLARI
List bileşeninde kullanımlarını örneklediğimiz add, addAll, length, remove kullanımları neredeyse tamamen aynı şekilde Set için de kullanılabilmektedir.

Tanımlama Kontrolü (Contains)

Tanımladığınız Set değerleri içerisinde bir anahtarın tanımlı olup olmadığını kontrol etmek isteyebilirsiniz. Bunun için .contains() ve .containsAll ifadelerini kullanacağız.

main() {
   var kisiler = {'Mehmet Ali VATANLAR', 'Şafak VATANLAR'};

   print(kisiler.contains('Mehmet')); // False
   print(kisiler.contains('Mehmet Ali Vatanlar')); // False
   print(kisiler.contains('Mehmet Ali VATANLAR')); // True
   
   print(kisiler.containsAll(['Mehmet Ali VATANLAR', 'Şafak VATANLAR'])); 
   // Birden fazla değer kontrolü :: True

   var kontrolEdilecekler = {'Mehmet Ali VATANLAR', 'Şafak VATANLAR'};
   print(kisiler.containsAll(kontrolEdilecekler));  // True
}

Kesişim Kümesi (intersection)

2 set dizesini kontrol ederek, 2 koleksiyon içerisinde de bulunan ortak anahtar değerlerini tespit etmemize olanak sağlar.

main() {
   var kisiListesi = {'Mehmet', 'Ahmet', 'Burak', 'Ayşe'};
   var gelenKisiler = {'Mehmet', 'Şafak'};

   var dogruGelenler = kisiListesi.intersection(gelenKisiler);
   print(dogruGelenler); // Mehmet çıktısını verir. (Çıktı Set olarak gönderilir.)
}

Birleşim Kümesi (union)

Bu metod ise tüm değerleri yalnızca 1 defa göstermek kaydı ile, iki koleksiyonun birleşmesini sağlar.

main() {
   var onceGelenler = {'Mehmet', 'Şafak', 'Derya', 'Hale'};
   var sonraGelenler = {'Mehmet', 'Mehmet', 'Deniz', 'Burak'};
   var tumGelenler = onceGelenler.union(sonraGelenler);
   print(tumGelenler);
}

Yukarıdaki örneğin çıktısı {Mehmet, Şafak, Derya, Hale, Deniz, Burak} şeklinde bir Set koleksiyonu olacaktır.

Map (Anahtarlı Veri Koleksiyonu)

Key ve value yapısında çalışan sırasız bir koleksiyon tipidir. Anahtarlar benzersiz olmak zorundadır. Benzersiz anahtarlar ile erişmeniz gereken nesneler tanımlamak için Map kullanabilirsiniz. Yine süslü parantezler (curly brackets) arasında tanımlama yapılır.

Ayrıca değerler arasına yerleştirilen virgül en sonda da bulundurulabilir. Bu hata vermez veya işlevselliği bozmaz.

main() {
   var ulkeBaskentleri = {
     'Turkey' : 'İstanbul',
     'İngiltere' : 'London',
     'Çin' : 'Beijing',
     'Almanya' : 'Berlin',
     'Nijerya' : 'Abuja',
     'Mısır' : 'Cairo',
     'Yeni Zelanda' : 'Wellington'
   };
 print(ulkeBaskentleri);
}

Yukarıdaki örnek 7 anahtar ve 7 değere sahiptir. Print etmek istediğinizde satır ayraçları olmadan tıpkı tanımlandığı gibi görüntülenecektir.

main() {
  var bosMap = Map();
  var bosMapTwo = Map<int, String>();
}

Değer ataması yapmadan bir Map koleksiyonu kurulumu yapmak için yukarıdaki ifade kullanılabilir. Ayrıca sonraki satırda gördüğünüz gibi anahtar (key) için farklı, değer (value) için farklı tip tanımlaması yapabilmekteyiz.

Map Koleksiyona Veri Ekleme

Map koleksiyonlar için kurulum yaparken anahtar ve değer için ayrı tür belirtebileceğimizden bahsetmiştik. Tanımlamak zorunda değiliz. Dart bizim için bu belirlemeyi yapabilmektedir. Ancak bu tarz durumlarda her zaman tedbirli olmakta fayda olacağını bilmeniz gerekir.

main() {
  var numaralar = Map<int, String>();
  // var numaralar = Map();

  numaralar[1] = 'Bir';
  numaralar[2] = 'İki';
  numaralar[3] = 'Üç';

  print(numaralar);
}

Map Koleksiyonu Eleman Sayısı

Burada da diğer koleksiyon tiplerinde olduğu gibi .length() kullanılabilmektedir. Bu özellik tüm koleksiyon türleri için kullanılabilir. Yukarıdaki örneğe göre numaralar.length() size 3 sonucunu döndürecektir.

Map Koleksiyonda Veriye Erişim

Map koleksiyonda verilere erişim anahtar değeri ile yapılmaktadır. Yukarıdaki koleksiyonu referans alacak olursak, aşağıdaki gibi bir yapıyla anahtar üzerinden erişim sağlayıp, değerinin çıktısını alabilirsiniz.

String turkiyeBaskenti = ulkeBaskentleri['Turkey'];
print(turkiyeBaskenti); // İstanbul

Olmayan bir anahtara başvurursanız geriye null değer dönecektir. Bu cevaptan korunmak için .containsKey() ile anahtarın tanımlı olup olmadığını kontrol edebilirsiniz.

Tüm anahtarları veya tüm değerleri ayrı ayrı almak isterseniz de aşağıdaki yöntemi kullanabilirsiniz.

var anahtarDegerleri = ulkeBaskentleri.keys;    
print("Anahtarlar: $anahtarDegerleri");

var degerler = ulkeBaskentleri.values;
print("Değerler: $degerler");  

Map Koleksiyonundan Veri Silme

Diğer koleksiyon tiplerinde olduğu gibi burada da .remove() metodu kullanılabilmektedir.

Kontrol İfadeleri ve Döngüler (if, else, elseif, while)

Dart dilinde kodlama yaparken bazı koşullara ve sonuçlara göre farklı işlemler yapmak veya farklı yollar izlemek isteyebilirsiniz.

Örneğin bir hesaplama yaptınız ve bu hesaplamanın sonucu 100 üzerinde ise sayıyı 100’e indirmek istiyorsunuz. Veya yaptığınız işlemin sonucuna göre çalıştıracağınız fonksiyonu, yapacağınız işlemi belirlemek istiyorsunuz. Bunun için koşul ifadelerini kullanabilirsiniz.

Başlıkta yazan kontrol ifadelerinin yanında, Dart dilinde bulunan kontrol ifadeleri baştan sona şöyledir; if ve else, for döngüsü, while ve do-while döngüsü, break ve continue, switch-case ve assert.

IF – ELSE Koşul İfadeleri

Bu ifade ile birlikte bir veya daha fazla koşulun sağlanması veya sağlanmaması halinde yapılacak işlemleri belirlemeniz amaçlanmıştır.

main() {
   var testListesi = [2,4,8,16,32];
   print(testListesi);
 if(testListesi.isNotEmpty){
     print("Liste boşaltılıyor.");
     testListesi.clear();
   }
 print(testListesi);
 }


Yukarıdaki örnekte bir liste oluşturduk. Bu listenin içerisindeki elemanları yazdırdığımızda bütün elemanları gördük. Sonrasında if ifadesi ile liste boş değil ise, “Liste boşaltılıyor.” çıktısını verip, listenin içini boşalttık. Ve sonra tekrar listeyi yazdırdık. Karşımıza aşağıdaki gibi bir sonuç geldi.

Burada kullandığımız isNotEmpty() fonksiyonu Dart tarafında List, Set ve Map tanımlamalarının içerisinin boş olup olmadığını kontrol eder.

Else ifadesini kullanmak istersek de, belirlediğimiz koşulun sağlanmadığı durumlarda çalışmasını istediğimiz bloğu else ifadesi içerisine yazabilmekteyiz. Hemen örnekleyecek olursak;

main() {
   var puanA = 53;
   var puanB = 61;
 if(puanA > puanB){
     print("A Takımı Kazandı!");
   } else {
     print("B Takımı Kazandı!");
   }
 }

Son olarak belirttiğimiz koşulun sağlanması ve sağlanmamasının haricinde, birden fazla koşulda yapılabilecek işlemleri sıralayabileceğimiz ELSE – IF yapısını görelim.

main() {
   var puanA = 50;
   var puanB = 50;
 if(puanA > puanB){
     print("A Takımı kazandı!");
   } else if(puanA > puanB) {
     print("B Takımı kazandı!");
   } else {
     print("Dostluk kazandı!");
   }
 }


Burada da iki koşulun da sağlanmaması halinde else içerisine girer ve bize sonucu gösterir.

Sadece 2 ihtimali olan IF ifadesi için kısa bir kullanım yolu mevcuttur. Bu neredeyse çoğu programlama dilinde aynıdır. Aşağıdaki örneği inceleyin.

main() {
   var a = 53;
   var b = 61;

   var fark = a > b ? a - b : b - a;
   var sonuc = a > b ? "A" : "B";
   
   print(fark);
   print(sonuc);
}


Bu örnekte a ve b değişkenlerinin değerleri fark ve sonuc değişkenlerine atanırken bazı kontroller yapılıyor. Fark değişkenine atanan değer a değişkeni b değişkeninden büyük ise a-b işlemini, değil ise b-a işlemini yapıp atıyor.

Sonuç değişkenine atanırken ise a değişkeni b değişkeninden büyük ise A metinsel ifadesi, değilse B metinsel ifadesi atanıyor.

For Döngüsü

Belli bir fonksiyonu veya işlemi 100 kez yapmanız gerektiğini düşünün. 100 adet hesaplama işlemi yapıp, 100 farklı sonucun çıktısını almanız gerekebilir. Bu işlemleri belli bir döngüye sokarak işlerinizi daha hızlı bir şekilde tamamlayın. For döngüsü de belirli bir koşul sağlandığı sürece işlem yapmaktadır. Örneğin 100 kez çalışsın isterseniz, bir değişkeni her çalıştığında 1 arttırarak, 100’e ulaşana kadar çalışmasını sağlamanız gerekmektedir.

main() {
   for(var i = 0; i < 5; i++){
     print(i);
   }
 }

Döngü yapısı ile bir koleksiyonun içerisindeki verileri sırası ile print edelim.

main() {
   var renkler = ['yeşil', 'mavi', 'bordo', 'kırmızı'];
   for(var i = 0; i < renkler.length; i++){
     print(renkler[i]);
   }
}

Aynı işlemi for in ile de kullanabiliriz. For-in ile kullandığımızda, her bir elemanı bir değişkene atamaktadır. Önceki örnekte 0’dan başlayan bir index değişkeni ile elemanları çağırıyorduk. Burada her değişken elemanın kendisini temsil etmektedir.

main() {
   var renkListesi = ['yeşil', 'mavi', 'pembe', 'mor'];
   for(var renk in renkListesi){
     print(renk);
   }
}

ForEach Fonksiyon Döngüsü

main() {
   var tester = [1,2,3];
   tester.forEach(print);
}

While Döngüsü

For döngüsü ile çok fazla benzerlik taşısa da, burada belirli bir koşul sağlandığı sürece döngü çalışır. Başlangıç ve bitiş noktası verilmesine gerek yoktur. Ali okuldan gelene kadar çalışsın derseniz, Ali’nin okuldan gelmesi ile sonlanır bu döngü.

main() {
  var sayac = 1;
  while (sayac <= 10) {
     print(sayac);
     sayac++;
  }
}

Yukarıdaki örnekte sayac isminde bir değişken tanımladık. Her döngü çalıştığında değeri 1 arttırdık. Ve döngü koşulunda sayac değişkeninin değerinin 10’dan küçük olması veya 10’a eşit olması halinde çalışabileceğini belirttik. Bu sayede bu döngü 10x kez çalışacaktır.

Do-While Döngüsü ile de kodu 1 kez çalıştırdıktan sonra koşul kontrol edilir. Yani koşul sağlanmadığı taktirde kod 1 kez çalışır, sonrasında koşul sağlanıyor ise tekrar çalışır, sağlanmıyor ise döngüden çıkılır.

main() {
  var alwaysOne = 1;
  do {
    print("Using do-while: $alwaysOne");
  } while (alwaysOne != 1);
}

Break ve Continue

Bu ifadeler de döngü içerisinde kullanılan ifadelerdir. Break satırı çalıştığında döngüyü tamamen iptal edip döngüden çıkış yapılır. Continue ifadesi ile ise, döngünün bir sonraki döngüye geçmesini sağlarız. Örneğin döngü içerisinde sonucun sıfır olması halinde çalıştırmak istemediğiniz kodlar var ise, continue kullanabilirsiniz.

Switch Case Koşul İfadesi

Switch-Case yapısı IF koşul ifadeleri ile benzer mantıkta çalışmaktadır. Aşağıdaki örneği inceleyebilirsiniz.

main() {
   var sonuc = 'AÇIK';
   switch(sonuc) {
     case 'KAPALI': 
       print('Kapı kapalı!');
       break;
     case 'AÇIK': 
       print('Kapı açık!');
       break;
     default:
       print('Kapı durumu bilinmiyor.');
  }
}

Fonksiyonlar

Dart programlama dili ile yaptığımız belirli işleri daha kolay kullanılabilir bir kod dizesi haline getirmek ve benzer işlemleri belli kodlarla tamamlayabilmek adına fonksiyonları kullanırız.

Yerleşik fonksiyonlar ve kullanıcı tanımlı fonksiyonlar olmak üzere 2 tip fonksiyon vardır. Yerleşik fonksiyonlar Dart dili ile beraber gelen, Dart geliştiricileri tarafından tanımlanmış sabit fonksiyonlardır. Kullanıcı tanımlı fonksiyonlar ise, bizim oluşturacağımız fonksiyonlardır.

Aşağıdaki örnekte kullandığımız print() bir fonksiyondur. Dart tarafında programlanmıştır. Konsola çıktı almaya yarayan bu fonksiyon yerleşik bir fonksiyondur. İçerisine gönderdiğimiz beniYazdir değişkeni ise, fonksiyonun aldığı parametredir.

Bir fonksiyon parametresiz çalıştırılabilir. 1 veya daha fazla parametre ile de çalıştırılabilir.

main() {
  var beniYazdir = "Mehmet Ali VATANLAR";
  print(beniYazdir);
}

Şimdi kendi fonksiyonumuzu tanımlayalım;



int add(int a, int b)
{
   int result = a + b;
   return result;
}

void main()
{
   var output = add(10, 20);
   print(output);
}

Parametresiz ve parametreli fonksiyonların kullanımının yanı sıra Optional parametreleri de köşeli parantezler ile belirtebiliriz. Bununla ilgili aşağıda bir örnek mevcut.

String mysteryMessage(String who, [String what, String where]){
  var message = '$who';
  if(what != null && where == null){
    message = '$message said $what';
  } else if (where != null){
    message = '$message said $what at $where';
  }
  return message;
}

main() {
  var result = mysteryMessage('Billy', 'howdy');
  print(result);
}

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir