Late Anahtar Kelimesi ve Null Safety
Coddy'nin Dart Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 26 / 110.
Bazen null olamayan (non-nullable) bir değişkene ihtiyaç duyarsınız, ancak değerini hemen atayamazsınız. late anahtar kelimesi Dart'a "Bunu kullanmadan önce başlatacağıma söz veriyorum." der.
late String description;
void setup() {
description = 'Initialized later';
}
void main() {
setup();
print(description); // Çalışır - kullanımdan önce başlatıldı
}late olmadan, Dart description değişkeninin başlatılmadığından şikayet ederdi. late ile, erişimden önce bir değere sahip olduğundan emin olma sorumluluğunu siz üstlenirsiniz. Eğer başlatmadan önce okumaya çalışırsanız, bir çalışma zamanı hatası alırsınız.
Yaygın bir kullanım durumu, gerçekten ihtiyaç duyulana kadar ertelemek istediğiniz maliyetli hesaplamalardır:
class DataProcessor {
late List<int> data = _loadData();
List<int> _loadData() {
print('Loading data...');
return [1, 2, 3, 4, 5];
}
}
DataProcessor processor = DataProcessor();
// 'Loading data...' henüz yazdırılmadı
print(processor.data); // Şimdi yüklenir ve yazdırılır_loadData() yöntemi, nesne oluşturulduğunda değil, yalnızca data öğesine ilk kez erişildiğinde çalışır. Bu tembel başlatma (lazy initialization), değere hiç ihtiyaç duyulmayabileceği durumlarda performansı artırabilir.
Bir değişkenin kullanılmadan önce ilklendirileceğinden emin olduğunuz ancak bunu bildirim anında yapamadığınız durumlarda late kullanın. Bu, derleyiciye verilmiş bir sözdür; bu sözü bozarsanız programınız çöker.
Görev
KolayErtelenmiş başlatma için late değişkenlerinin gücünü gösteren bir yapılandırma yöneticisi oluşturalım. Yapılandırmanın gerçekten ihtiyaç duyulduğu ana kadar maliyetli kurulum işlemlerinin gerçekleşmediği bir sistem oluşturacaksınız.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
config_manager.dart: Uygulama ayarlarını yöneten birConfigManagersınıfı tanımlayın. Sınıf şunlara sahip olmalıdır:- Yapıcı (constructor) aracılığıyla iletilen bir
String appName - Daha sonra bir kurulum yöntemi aracılığıyla başlatılacak olan bir
late String databaseUrl - İlk erişildiğinde
Calculating max connections...yazdıran ve100değerini döndüren, tembel başlatmalı (lazy initialization) birlate int maxConnections databaseUrldeğişkenini başlatan birsetupDatabase(String url)metodu- Mevcut yapılandırmayı yazdıran bir
displayConfig()metodu
- Yapıcı (constructor) aracılığıyla iletilen bir
main.dart: Yapılandırma yöneticinizi içe aktarın ve late değişkenlerin nasıl çalıştığını gösterin:- Uygulama adı
'MyApp'olan birConfigManageroluşturun Config createdyazdırın'localhost:5432/mydb'URL'si ilesetupDatabasemetodunu çağırınAccessing max connections...yazdırınmaxConnectionsdeğerini yazdırınAccessing max connections again...yazdırınmaxConnectionsdeğerini tekrar yazdırın (hesaplama mesajının tekrarlanmadığına dikkat edin)displayConfig()metodunu çağırın
- Uygulama adı
displayConfig() metodu şu formatta yazdırmalıdır:
--- Configuration ---
App: [appName]
Database: [databaseUrl]
Max Connections: [maxConnections]Tembel (lazy) maxConnections hesaplamasının yalnızca bir kez -ona ilk eriştiğinizde- nasıl çalıştığına dikkat edin. Bu, bir başlatıcı ile birlikte late kullanmanın avantajıdır!
Beklenen çıktı:
Config created
Accessing max connections...
Calculating max connections...
100
Accessing max connections again...
100
--- Configuration ---
App: MyApp
Database: localhost:5432/mydb
Max Connections: 100Kopya kağıdı
late anahtar kelimesi, kullanılmadan önce daha sonra başlatılacak olan null yapılamaz (non-nullable) değişkenler tanımlamanıza olanak tanır:
late String description;
void setup() {
description = 'Initialized later';
}
void main() {
setup();
print(description); // Works - initialized before use
}late olmadan, Dart anında başlatma gerektirir. late ile, değişkene erişmeden önce onu başlatacağınıza dair söz verirsiniz. Başlatılmamış bir late değişkenini okumak, çalışma zamanı hatasına (runtime error) neden olur.
Tembel Başlatma (Lazy Initialization): Bir late değişkeninin bir başlatıcısı (initializer) olduğunda, başlatma işlemi değişkene ilk kez erişilene kadar ertelenir:
class DataProcessor {
late List<int> data = _loadData();
List<int> _loadData() {
print('Loading data...');
return [1, 2, 3, 4, 5];
}
}
DataProcessor processor = DataProcessor();
// 'Loading data...' hasn't printed yet
print(processor.data); // Now it loads and prints_loadData() yöntemi, nesne oluşturulduğunda değil, yalnızca data değişkenine ilk kez erişildiğinde çalışır. Bu, değerin hiç gerekmediği durumlarda veya başlatma işleminin maliyetli olduğu durumlarda performansı artırır.
Kendin dene
import 'config_manager.dart';
void main() {
// TODO: 'MyApp' uygulama adıyla bir ConfigManager oluşturun
// TODO: 'Config created' yazdırın
// TODO: 'localhost:5432/mydb' URL'si ile setupDatabase'i çağırın
// TODO: 'Accessing max connections...' yazdırın
// TODO: maxConnections değerini yazdırın
// TODO: 'Accessing max connections again...' yazdırın
// TODO: maxConnections değerini tekrar yazdırın
// (hesaplama mesajının tekrarlanmadığına dikkat edin)
// TODO: displayConfig() fonksiyonunu çağırın
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarKütüphaneler ve ImportlarOOP'ye GirişSınıflar ve Nesnelerthis Anahtar KelimesiMetotlarÖrnek DeğişkenleriConstructor TemelleriÖzet - Basit Hesap Makinesi4Null Safety
Null Safety'ye GirişNullable ve Non-Nullable? ve ! OperatörleriLate Anahtar Kelimesi ve Null SafetyNull-Aware OperatörleriSınıflarda Null SafetyÖzet - Kullanıcı Profili Sistemi7Soyut Sınıflar ve Arayüzler
Soyut SınıflarSoyut MetotlarDart'ta ArayüzlerÖrtük ArayüzlerUygulama vs. GenişletmeÇoklu ArayüzlerÖzet - Şekil Hesaplayıcı10Koleksiyonlar ve Generic'ler
List, Set, Map Genel BakışTip Güvenli KoleksiyonlarGeneric SınıflarGeneric MetotlarGeneric KısıtlamalarIterable ve IteratorÖzet - Generic Depolama2Dart'ta Yapıcılar
Varsayılan Yapıcıİsimlendirilmiş Yapıcılarİlklendirme ListeleriSabit YapıcılarFabrika YapıcılarıYönlendiren YapıcılarÖzet - Şekil Oluşturucu5Kapsülleme
Public ve Private Üyeler_ Öneki KuralıKütüphane Düzeyinde GizlilikGetter ve Setter DetaylarıBilgi GizlemeÖzet - Öğrenci Kayıtları8Mixin'ler
Mixin'lere GirişMixin OluşturmaBirden Fazla Mixin KullanımıMixin'lerde on Anahtar KelimesiMixin vs KalıtımMixin vs ArayüzÖzet - Hayvan Sistemi11Özel Metotlar
toString() OverridehashCode ve == OverrideComparable Arayüzücall() MetodunoSuchMethod OverrideÖzet - Özel Koleksiyon14Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı17Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakter SistemiAraç Kiralama Servisi3Sınıf Özellikleri
Instance ve Statik ÜyelerFinal ve Const AlanlarLate DeğişkenlerStatik Metotlar ve AlanlarGetters ve SettersÖzet - Banka Hesabı Yöneticisi6Kalıtım
Temel Kalıtımsuper Anahtar KelimesiMetot Ezme@override Anotasyonufinal Sınıf Anahtar KelimesiYapıcı Metotlar ve KalıtımÖzet - Çalışan Hiyerarşisi9Çok Biçimlilik
Çok Biçimlilik TemelleriInterface'ler ile Çok BiçimlilikÇalışma Zamanı Tip Kontrolüis ve as OperatörleriCovariant Anahtar KelimesiÖzet - Ödeme İşlemcisi12Asenkron OOP
Futures ve async/awaitStream TemelleriStream Controller'larAsenkron KurucularSınıf Metotlarında Asenkron KullanımıÖzet - Data Fetcher15Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit KalıbıRepository Kalıbı