Kayıtlar (Records)

Dart dilinde, kayıtlar (records) anonim, değişmez ve birleşik bir türdür. Diğer koleksiyon türleri gibi, birden çok nesneyi tek bir nesne içinde paketlemenizi sağlar. Ancak kayıtlar, sabit boyutlu, heterojen ve tip belirlidir.

Kayıt Sözdizimi

Kayıt ifadeleri, adlandırılmış veya konumsal alanların parantez içinde virgülle ayrılmış listeleridir:

var kayit = ('ilk', a: 2, b: true, 'son');

Kayıt türü açıklamaları, parantez içinde virgülle ayrılmış tür listeleridir. Bu açıklamaları kullanarak dönüş ve parametre türlerini tanımlamak mümkündür.

(int, int) swap((int, int) kayit) {
  var (a, b) = kayit;
  return (b, a);
}

Kayıt ifadesindeki sıralı alanlar, parantez içine doğrudan yerleştirilir:

// Bir değişken bildiriminde kayıt türü açıklaması:
(String, int) kayit;

// Bir kayıt ifadesi ile başlat:
kayit = ('Bir dize', 123);

Kayıt türü açıklamasında, adlandırılmış alanlar, tüm konumsal alanlardan sonra gelen bir tip ve isim çiftlerinden oluşan bir parantez içinde yer alır. Bir kayıt ifadesinde isimler, her alan değerinden önce gelen bir ikinci nokta üst üste ile belirtilir:

// Bir değişken bildiriminde kayıt türü açıklaması:
({int a, bool b}) kayit;

// Bir kayıt ifadesi ile başlat:
kayit = (a: 123, b: true);

Adlandırılmış alanların isimleri, bir kayıt türünün tanımı veya şekli olan kayıt türünün bir parçasıdır. Farklı isimlere sahip adlandırılmış alanlara sahip iki kayıt, farklı tiplere sahiptir:

({int a, int b}) kayitAB = (a: 1, b: 2);
({int x, int y}) kayitXY = (x: 3, y: 4);

// Derleme hatası! Bu kayıtlar aynı tipe sahip değil.
// kayitAB = kayitXY;

Kayıt türü açıklamasında konumsal alanlara da isim verilebilir, ancak bu isimler sadece belgeleme amaçlıdır ve kaydın türünü etkilemez:

(int a, int b) kayitAB = (1, 2);
(int x, int y) kayitXY = (3, 4);

kayitAB = kayitXY; // Tamam.

Bu, bir fonksiyon bildirimi veya fonksiyon typedef'indeki konumsal parametrelerin adlandırılabilir olduğu, ancak bu isimlerin fonksiyonun imzasını etkilemediği şekilde çalışır.

Kayıt Alanları

Kayıt alanlarına, yerleşik getter'lar aracılığıyla erişilebilir. Kayıtlar değişmez olduğundan, alanlara setter'lar eklenmez.

Adlandırılmış alanlar, aynı adı taşıyan getter'lara sahiptir. Konumsal alanlar ise adlandırılmış alanları atlayarak $<position> adında getter'lara sahiptir:

var kayit = ('ilk', a: 2, b: true, 'son');

print(kayit.$1); // 'ilk' yazdırılır
print(kayit.a);  // 2 yazdırılır
print(kayit.b);  // true yazdırılır
print(kayit.$2); // 'son' yazdırılır

Kayıt alanlarına daha hızlı erişim için Desenler sayfasına göz atabilirsiniz.

Kayıt Tipleri

Bireysel kayıt tipleri için tip bildirimi yoktur. Kayıtlar, alanlarının türlerine dayalı olarak yapısal olarak tipi belirlenen bir yapıya sahiptir. Bir kaydın şekli (alanlarının kümesi, alan türleri ve isimleri, varsa) bir kaydın türünü benzersiz olarak belirler.

Bir kayıttaki her alanın kendi türü vardır ve aynı kayıt içinde farklı türlerde olabilir. Tür sistemi, bir alanın türünü kayıttan nerede erişildiği konusunda bilir:

(num, Object) cift = (42, 'a');

var ilk = cift.$1; // Statik tip `num`, çalışma zamanı tipi `int`.
var ikinci = cift.$2; // Statik tip `Object`, çalışma zamanı tipi `String`.

Aynı alan kümesine sahip iki bağlantısız kütüphaneyi düşünün. Tür sistemi, bu kayıtların aynı tür olduğunu anlar, ancak kütüphaneler birbirine bağlı değildir.

Kayıt Eşitliği

İki kayıt, aynı şekle (alan kümesi) sahipse ve karşılık gelen alanları aynı değerlere sahipse eşittir. Adlandırılmış alan sırası, bir kaydın şeklinin bir parçası olmadığından, adlandırılmış alanların sırası eşitliği etkilemez.

Örneğin:

(int x, int y, int z) nokta = (1, 2, 3);
(int r, int g, int b) renk = (1, 2, 3);

print(nokta == renk); // 'true' yazdırılır.
({int x, int y, int z}) nokta = (x: 1, y: 2, z: 3);
({int r, int g, int b}) renk = (r: 1, g: 2, b: 3);

print(nokta == renk); // 'false' yazdırılır. Lint: Farklı türlerde eşittir.

Kayıtlar otomatik olarak alan yapılarına dayalı hashCode ve == metodlarını tanımlar.

Çoklu Değer Döndürme

Kayıtlar, fonksiyonların bir araya topluca birden çok değer döndürmelerine olanak tanır. Kayıt değerlerini bir dönüşten almak için desen eşleme kullanarak değerleri yerel değişkenlere çözebilirsiniz:

// Bir kayıt içinde birden çok değer döndür:
(String, int) kullaniciBilgisi(Map<String, dynamic> json) {
  return (json['isim'] as String, json['yas'] as int);
}

final json = <String, dynamic>{
  'isim': 'Dash',
  'yas': 10,
  'renk': 'mavi',
};

// Kayıt deseni kullanarak çöz:
var (isim, yas) = kullaniciBilgisi(json);

/* Şu ile eşdeğer:
  var bilgi = kullaniciBilgisi(json);
  var isim = bilgi.$1;
  var yas  = bilgi.$2;
*/

Kayıtlar olmadan bir fonksiyondan çoklu değer döndürmek mümkündür, ancak diğer yöntemler dezavantajlarla gelir. Örneğin, bir sınıf oluşturmak daha çok sözdizimi gerektirir ve List veya Map gibi diğer koleksiyon türlerini kullanmak tip güvenliğini kaybetmenize neden olabilir.

Not

Kayıtların çoklu dönüş ve heterojen tip özellikleri, farklı türlerdeki gelecekleri paralel hale getirme olanağı sağlar.

Bu konuyla ilgili daha fazla bilgi için dart:async belgelerine bakabilirsiniz.

Last updated