Dart Diline Giriş #1

MÜŞERREF SELÇUK ÖZDEMIR
7 min readNov 28, 2023

--

Dart

Dart, Google tarafından geliştirilen, genel amaçlı bir programlama dilidir. İlk olarak 2011 yılında duyurulan Dart, özellikle web ve mobil uygulama geliştirmek için tasarlanmıştır. Hem tarayıcıda çalışabilen hem de kendi başına çalışabilen uygulamalar oluşturmak için kullanılabilen bu dil, özellikle Google’ın Flutter çerçevesiyle birlikte popülerlik kazanmıştır

Dart’ın en temel özelliği hız ve performansı sağlamak üzere tasarlanmasıdır. JavaScript’in yerine geçmesi beklenen bu dil günümüzde web dışındaki birçok platformda kullanılmaya başlanmıştır.

Geliştiriciler için Dart’ın nesne yönelimli ve modern bir dil olması sürdürülebilir ve anlaşılır kod yazma olanağı sunar. Dart ayrıca diğer dillerden ayrı olarak tip kontrolü bulundurur. Böylelikle hatalar daha kod çalışmadan tespit edilir.

Şimdi Dart’a giriş yapalım:

Hello World — Merhaba Dünya

Her uygulama, yürütmenin başladığı en üst düzey main() fonksiyonuna ihtiyaç duyar. Açıkça bir değer döndürmeyen fonksiyonlar void dönüş tipine sahiptir. Konsolda metin görüntülemek için en üst düzey print() fonksiyonunu kullanabilirsiniz:

void main() {
print('Hello, World!');
}

Variables — Değişkenler

Tip güvenli (type-safe) Dart kodunda bile, var kullanarak tiplerini açıkça belirtmeden çoğu değişkeni bildirebilirsiniz. Tip çıkarımı sayesinde, bu değişkenlerin tipleri ilk değerleri tarafından belirlenir:

var name = 'Memati Baş';
var year = 1964;
var inc= 3.7;
var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
var image = {
'tags': ['saturn'],
'url': '//path/to/saturn.jpg'
};

Control flow statements — Kontrol akışı ifadeleri

Dart bilinen kontrol akışı ifadelerini destekler:

if (year >= 2001) {
print('21st century');
} else if (year >= 1901) {
print('20th century');
}

for (final object in flybyObjects) {
print(object);
}

for (int month = 1; month <= 12; month++) {
print(month);
}

while (year < 2016) {
//do something
year += 1;
}

Functions — Fonksiyonlar

Her fonksiyonun değişkenlerinin ve dönüş değerlerinin türlerinin yazarak belirtilmesi önerilir:

int fibonacci(int n) {
if (n == 0 || n == 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}

var result = fibonacci(20);

Tek bir ifade içeren fonksiyonlar için kısaltılmış => (ok) sözdizimi kullanışlıdır. Bu sözdizimi özellikle anonim fonksiyonları argüman olarak geçirirken kullanışlıdır:

flybyObjects.where((name) => name.contains('turn')).forEach(print);

Bu kod, anonim bir fonksiyonu(where() argümanı) göstermenin yanı sıra, bir fonksiyonu argüman olarak kullanabileceğinizi de gösterir: üst düzey print() işlevi forEach() fonksiyonunun bir argümanıdır.

where(): Bu fonksiyon, belirli bir koşulu sağlayan elemanları içeren yeni bir koleksiyon oluşturur. Burada, name.contains(‘turn’) koşulu sağlanan elemanları içeren bir koleksiyon oluşturulur.

(name) => name.contains(‘turn’) : Bu kısım, bir lambda fonksiyonunu temsil eder. Bu fonksiyon, her elemanın (name) "turn" kelimesini içerip içermediğini kontrol eder.

Comments — Yorumlar

// Bu bir satırlık bir yorumdur

/// Bu, kütüphaneleri belgelemek için kullanılan bir belgeleme yorumudur
/// IDE'ler ve dartdoc gibi araçlar doküman yorumlarını özel olarak ele alır.

/* Bu tip yorumlarda kabul edilir. */

Imports — İçe Aktarım

Diğer kütüphanelerde tanımlanan API’lere erişmek için import kullanılır.

// Çekirdek kütüphaneleri içe aktarma

import 'dart:math';

// Dış paketlerden kütüphane içe aktarımı
import 'package:test/test.dart';

// Dosyaları içe aktarma
import 'path/to/my_other_file.dart';

Classes — Sınıflar

İşte üç özelliği (properties), iki kurucusu(constructor) ve bir metodu olan bir sınıf örneği. Özelliklerden biri doğrudan ayarlanamaz, bu nedenle bir getter yöntemi (değişken yerine) kullanılarak tanımlanır. Yöntem, değişkenlerin dize eşdeğerlerini dize değişmezlerinin içine yazdırmak için dize enterpolasyonu kullanır.

class Spacecraft {
String name;
DateTime? launchDate;

// Salt okunur nihai(final) olmayan özellik
int? get launchYear => launchDate?.year;

// Kurucu, üyelere atama için sözdizimsel şeker.
Spacecraft(this.name, this.launchDate) {
// Başlatma kodu buraya
}

// Named constructor that forwards to the default one.
Spacecraft.unlaunched(String name) : this(name, null);

// Method.
void describe() {
print('Spacecraft: $name');
// Type promotion doesn't work on getters.
var launchDate = this.launchDate;
if (launchDate != null) {
int years = DateTime.now().difference(launchDate).inDays ~/ 365;
print('Launched: $launchYear ($years years ago)');
} else {
print('Unlaunched');
}
}
}

Spacecraft sınıfı şu şekilde kullanılabilir:

var voyager = Spacecraft('Voyager I', DateTime(1977, 9, 5));
voyager.describe();

var voyager3 = Spacecraft.unlaunched('Voyager III');
voyager3.describe();

Enums — Sıralamalar

Enumlar, önceden tanımlanmış bir değerler veya örnekler kümesini, o türden başka örneklerin olamayacağını garanti edecek şekilde numaralandırmanın bir yoludur.

İşte önceden tanımlanmış gezegen türlerinin basit bir listesini tanımlayan basit bir enum örneği:

enum PlanetType { terrestrial, gas, ice }

Burada, gezegenleri tanımlayan bir sınıfın, tanımlanmış bir dizi sabit örnekle, yani kendi güneş sistemimizin gezegenleriyle, geliştirilmiş enum bildirimine bir örnek verilmiştir.

/// Enum that enumerates the different planets in our solar system
/// and some of their properties.
enum Planet {
mercury(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
venus(planetType: PlanetType.terrestrial, moons: 0, hasRings: false),
// ···
uranus(planetType: PlanetType.ice, moons: 27, hasRings: true),
neptune(planetType: PlanetType.ice, moons: 14, hasRings: true);

/// A constant generating constructor
const Planet(
{required this.planetType, required this.moons, required this.hasRings});

/// All instance variables are final
final PlanetType planetType;
final int moons;
final bool hasRings;

/// Enhanced enums support getters and other methods
bool get isGiant =>
planetType == PlanetType.gas || planetType == PlanetType.ice;
}

Planet enum şu şekilde kullanılabilir:

final yourPlanet = Planet.earth;

if (!yourPlanet.isGiant) {
print('Your planet is not a "giant planet".');
}

Inheritance — Kalıtım

Dart’ın tek bir kalıtımı vardır.

class Orbiter extends Spacecraft {
double altitude;

Orbiter(super.name, DateTime super.launchDate, this.altitude);
}

Mixins — Karışımlar

Karışımlar, birden fazla sınıf hiyerarşisinde kodu yeniden kullanmanın bir yoludur. Aşağıda bir mixin bildirimi verilmiştir:

mixin Piloted {
int astronauts = 1;

void describeCrew() {
print('Number of astronauts: $astronauts');
}
}

Bir mixin’in yeteneklerini bir sınıfa eklemek için, sınıfı mixin ile genişletmeniz yeterlidir.

class PilotedCraft extends Spacecraft with Piloted {
// ···
}

PilotedCraft artık astronauts alanının yanı sıra describeCrew() yöntemine de sahip.

Interfaces and Abstract Classes — Kalıtım ve Soyut Sınıflar

Tüm sınıflar örtük olarak bir arayüz tanımlar. Bu nedenle, herhangi bir sınıfı uygulayabilirsiniz.

class MockSpaceship implements Spacecraft {
// ···
}

Somut bir sınıf tarafından genişletilmek (veya uygulanmak) üzere soyut bir sınıf oluşturabilirsiniz. Soyut sınıflar soyut yöntemler (boş gövdeli) içerebilir.

abstract class Describable {
void describe();

void describeWithEmphasis() {
print('=========');
describe();
print('=========');
}
}

Describable genişleten herhangi bir sınıf, genişleticinin describe() uygulamasını çağıran describeWithEmphasis() yöntemine sahiptir.

Async — Asenkron

Geri arama cehenneminden kaçının ve async and await kullanarak kodunuzu çok daha okunabilir hale getirin.

const oneSecond = Duration(seconds: 1);
// ···
Future<void> printWithDelay(String message) async {
await Future.delayed(oneSecond);
print(message);
}

Yukarıdaki yöntem şuna eşdeğerdir:

Future<void> printWithDelay(String message) {
return Future.delayed(oneSecond).then((_) {
print(message);
});
}

Bir sonraki örnekte gösterildiği gibi, async ve await asenkron kodun okunmasını kolaylaştırır.

Future<void> createDescriptions(Iterable<String> objects) async {
for (final object in objects) {
try {
var file = File('$object.txt');
if (await file.exists()) {
var modified = await file.lastModified();
print(
'File for $object already exists. It was modified on $modified.');
continue;
}
await file.create();
await file.writeAsString('Start describing $object in this file.');
} on IOException catch (e) {
print('Cannot create description for $object: $e');
}
}
}

Ayrıca async* kullanabilirsiniz, bu da size akış oluşturmak için güzel ve okunabilir bir yol sunar.

Stream<String> report(Spacecraft craft, Iterable<String> objects) async* {
for (final object in objects) {
await Future.delayed(oneSecond);
yield '${craft.name} flies by $object';
}
}

Exceptions — İstisnalar

Bir istisna oluşturmak için throw kullanın:

if (astronauts == 0) {
throw StateError('No astronauts.');
}

Bir istisnayı yakalamak için on ya da catch (ya da her ikisi) içeren bir try deyimi kullanın:

Future<void> describeFlybyObjects(List<String> flybyObjects) async {
try {
for (final object in flybyObjects) {
var description = await File('$object.txt').readAsString();
print(description);
}
} on IOException catch (e) {
print('Could not describe object: $e');
} finally {
flybyObjects.clear();
}
}

Note that the code above is asynchronous; works for both synchronous code and code in an async function.

Yukarıdaki kodun eşzamansız olduğuna dikkat edin; try hem eşzamanlı kod hem de bir async işlev içindeki kod için çalışır.

Important Concepts — Önemli Konseptler

Dart dili hakkında bilgi edinmeye devam ederken, bu gerçekleri ve kavramları aklınızda tutun:

  • Bir değişkene yerleştirebileceğiniz her şey bir nesnedir ve her nesne bir sınıfın örneğidir. Sayılar, fonksiyonlar ve null bile nesnedir. Null hariç (null güvenliğini etkinleştirirseniz), tüm nesneler Object sınıfından miras alır.
  • Dart güçlü tiplemeli olmasına rağmen, tip ek açıklamaları isteğe bağlıdır çünkü Dart tipleri çıkarabilir. var number = 101 ifadesinde, sayının int türünde olduğu çıkarılır.
  • Null safety, etkinleştirirseniz, siz söylemediğiniz sürece değişkenler null içeremez. Bir değişkeni, türünün sonuna bir soru işareti (?) koyarak null yapılabilir hale getirebilirsiniz. Örneğin, int? türündeki bir değişken bir tamsayı olabilir veya null olabilir. Bir ifadenin asla null olarak değerlendirilmeyeceğini biliyorsanız, ancak Dart aynı fikirde değilse, null olmadığını iddia etmek (ve eğer öyleyse bir istisna fırlatmak) için ! ekleyebilirsiniz. Bir örnek: int x = nullableButNotNullInt!
  • Herhangi bir türe izin verildiğini açıkça söylemek istediğinizde, Object? (null güvenliğini etkinleştirdiyseniz), Object veya — tür denetimini çalışma zamanına kadar ertelemeniz gerekiyorsa — özel dynamic türünü kullanın.
  • Dart, List<int> (tamsayıların listesi) veya List<Object> (herhangi bir türdeki nesnelerin listesi) gibi genel türleri destekler.
  • Dart, üst düzey fonksiyonların ( main() gibi) yanı sıra bir sınıfa veya nesneye bağlı fonksiyonları da (sırasıyla statik ve örnek metotlar) destekler. Ayrıca fonksiyonlar içinde fonksiyonlar da oluşturabilirsiniz (iç içe veya yerel fonksiyonlar).
  • Benzer şekilde, Dart üst düzey değişkenlerin yanı sıra bir sınıfa veya nesneye bağlı değişkenleri de (statik ve örnek değişkenler) destekler. Örnek değişkenler bazen alanlar veya özellikler olarak bilinir.
  • Java’nın aksine, Dart’ta public, protected, ve private anahtar sözcükleri yoktur. Eğer bir tanımlayıcı alt çizgi (_) ile başlıyorsa, kütüphanesine özeldir. Ayrıntılar için Kütüphaneler ve içe aktarmalar bölümüne bakınız.
  • Tanımlayıcılar bir harf veya alt çizgi (_) ile başlayabilir, ardından bu karakterlerin herhangi bir kombinasyonu artı rakamlar gelebilir.
  • Dart hem ifadelere (çalışma zamanı değerleri olan) hem de deyimlere (olmayan) sahiptir. Örneğin, condition ? expr1 : expr2 koşullu ifadesi expr1 veya expr2 değerine sahiptir. Bunu, değeri olmayan bir if-else ifadesiyle karşılaştırın. Bir deyim genellikle bir veya daha fazla ifade içerir, ancak bir ifade doğrudan bir deyim içeremez.
  • Dart araçları iki tür sorun bildirebilir: uyarılar ve hatalar. Uyarılar sadece kodunuzun çalışmayabileceğine dair göstergelerdir, ancak programınızın çalışmasını engellemezler. Hatalar derleme zamanı ya da çalışma zamanı olabilir. Derleme zamanı hatası kodun çalışmasını engeller; çalışma zamanı hatası ise kod çalışırken bir istisna oluşmasına neden olur.

--

--