Swift dilindeki subscript mekanizması 2014 yılında dil ile birlikte ortaya çıkmış ve koleksiyonlardaki verilere daha kullanışlı bir sözdizimi ile erişim sağlamak için tasarlanmıştır. Subscripts, dizilerin, sözlüklerin ve diğer koleksiyonların elemanlarına köşeli parantezler aracılığıyla erişmeyi mümkün kılmaktadır. Modern Swift, kendi türleriniz için kullanıcı tanımlı subscripts oluşturmayı mümkün hale getirerek API'yi standart veri yapıları gibi sezgisel hale getirir.
Sorun: Önceden erişim yöntemleri daha karmaşık görünüyordu (örneğin, .getElement(at:)), ancak subscript, türle etkileşimi daha sade hale getirir. Ancak, yanlış bir uygulama, kodun verimsiz olmasına veya koleksiyonun dışına erişim hatalarına yol açabilir.
Çözüm: Subscript'i uygulamak için subscript anahtar kelimesi kullanılır; ardından parametreler ve dönüş değeri belirtilir. Subscript yalnızca okuma (read-only) veya hem okuma hem de yazma (read-write) için olabilir. Ayrıca, subscripts farklı parametreler için aşırı yüklenebilir.
Kod örneği:
struct Matrix { let rows: Int let columns: Int var grid: [Double] init(rows: Int, columns: Int) { self.rows = rows self.columns = columns self.grid = Array(repeating: 0.0, count: rows * columns) } subscript(row: Int, column: Int) -> Double { get { assert(row >= 0 && row < rows && column >= 0 && column < columns, "Dizin aralık dışı") return grid[(row * columns) + column] } set { assert(row >= 0 && row < rows && column >= 0 && column < columns, "Dizin aralık dışı") grid[(row * columns) + column] = newValue } } } var matrix = Matrix(rows: 2, columns: 2) matrix[0, 1] = 3.14 print(matrix[0, 1]) // 3.14
Anahtar Özellikler:
Sadece okuma için subscript atayabilir miyiz? Yoksa subscript her zaman get ve set içermeli mi?
Subscript yalnızca okumak için (sadece get) olabilir; eğer implementasyonda set yoksa. Her iki erişim aracını uygulamak zorunda değilsiniz; bu, özelliklere benzer.
Kod örneği:
subscript(index: Int) -> Int { get { return index * 2 } }
Subscript içinde değişken parametreleri inout ile geçirebilir miyiz?
Hayır, subscript, imzasında inout parametrelerini desteklemez. Tüm subscript parametreleri accessor gövdesi içinde let sabitleri olarak kabul edilir.
Subscripts isteğe bağlı bir tür döndürebilir mi?
Evet, subscripts isteğe bağlı değerler döndürebilir, bu da koleksiyon elemanlarına güvenli bir şekilde erişim sağlamak için yararlıdır ve dizi dışına çıkma riski olmadan erişim sağlar.
Kod örneği:
extension Array { subscript(safe index: Int) -> Element? { return indices.contains(index) ? self[index] : nil } }
Sınır dışı doğrulama olmadan subscript uygulamak, matris türü için yapı, indeks hataları durumunda uygulamanın çökmesine yol açar.
Artılar:
Eksiler:
Güvenli indeksleme ve hata işleme için isteğe bağlı bir subscript versiyonu eklenmiştir; bu da API'yi açık ve korunaklı hale getirir.
Artılar:
Eksiler: