ProgramlamaiOS geliştirici

Swift'te subscripting nedir ve kendi yapınız için özel bir subscript nasıl uygulanır?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Sorunun Geçmişi:

Subscript, koleksiyonlar, yapılar ve diğer türler içindeki değerlere köşeli parantezler aracılığıyla erişme mekanizmasıdır. Diğer dillerle (örneğin, Python'daki dizinleme, C++/Java'daki [] operatörü) benzerlik göstermek üzere Swift'e eklenmiştir, böylece koleksiyonlar ve benzeri nesnelerle çalışma daha sezgisel hale gelir.

Problemler:

Tüm türler varsayılan olarak dizine göre erişimi desteklemez. Veri içeren bir yapı veya sınıfımız olduğunda, elemanlara erişim genellikle alışıldık söz dizimi (örneğin myObject[index]) aracılığıyla gerçekleştirilmesi daha mantıklıdır, yöntem aracılığıyla değil.

Çözüm:

Swift, her kullanıcı tanımlı tür için subscripting'i kendinizin uygulamasına izin verir. Bunu hem okuma hem de yazma için yapabilirsiniz. Örnek olarak, kare matrisle çalışmak için subscript'i uygulayan bir yapı:

struct Matrix { let size: Int private var grid: [Int] init(size: Int) { self.size = size self.grid = Array(repeating: 0, count: size * size) } subscript(row: Int, column: Int) -> Int { get { precondition(indexIsValid(row, column), "Index out of range") return grid[(row * size) + column] } set { precondition(indexIsValid(row, column), "Index out of range") grid[(row * size) + column] = newValue } } private func indexIsValid(_ row: Int, _ column: Int) -> Bool { return row >= 0 && row < size && column >= 0 && column < size } } var m = Matrix(size: 3) m[1,2] = 7 print(m[1,2]) // 7

Anahtar özellikler:

  • Subscript, yalnızca bir indeks değil, herhangi bir sayıda argüman alabilir.
  • subscript anahtar kelimesi ile uygulanır ve yalnızca get veya get/set olabilir.
  • Kullanıcı tanımlı koleksiyonlar veya yapılar için kullanışlı ve okunabilir bir API oluşturmanıza olanak tanır.

Kandırmaca Sorular.

Subscript yalnızca koleksiyonlar için mi kullanılabilir?

Hayır, subscript herhangi bir tür için uygulanabilir: yapı, sınıf, enum. İçindeki veri türü bir koleksiyon olmak zorunda değildir, önemli olan subscript aracılığıyla sorgu işleme mantığıdır.

Bir türde farklı imzaya sahip birden fazla subscript oluşturmak mümkün mü?

Evet, farklı parametre imzalarına sahip subscript'leri aşırı yüklemek mümkündür:

struct Example { subscript(index: Int) -> Int { return index } subscript(key: String) -> String { return key.uppercased() } }

Subscript, set olmadan hesaplanmış bir özellik olarak kullanılabilir mi?

Evet, subscript yalnızca okuma (get-only) olabilir, bu durumda yazma girişimi derleme hatasına neden olur.

struct ReadOnly { subscript(index: Int) -> Int { index * index } }

Tipik Hatalar ve Anti-Desenler

  • Dizin aralığı kontrolünün olmaması (Index out of range)
  • “Tek Sorumluluk” ilkesinin ihlali — subscript iş mantığını içerir, yalnızca verilere erişim sağlamaz.
  • Çok karmaşık ve belirsiz subscript imzaları.

Gerçek Hayat Örneği

Olumsuz Durum

Büyük bir yapıda aralık kontrolü olmadan bir subscript uygulanır, bu da yanlış bir indeksle uygulamanın çökmesine neden olur.

Artılar:

  • Hızlı prototip
  • Daha az kod

Eksiler:

  • Yüksek runtime-crash olasılığı
  • Belirsiz bir hata nedeniyle hata ayıklamada zorluk

Olumlu Durum

Matris, indeks aralığı için precondition ile uygulanmıştır. Herhangi bir hata hemen yakalanır, produksiyona ulaşmaz.

Artılar:

  • Girdilerle çalışırken güvenlik
  • Kolay teşhis ve bakım

Eksiler:

  • Biraz daha fazla kod ve kontrol, ancak güvenilirlik artar.