Swift’te Struct ve Class Arasındaki Farklar Nelerdir?

Apple tarafından geliştirilen Swift; esnekliği, güvenliği ve modernliği ile geliştiricilere birçok kolaylık sağlıyor. Birçok yerde ve şekilde kullandığımız veri modelleri bunların başında geliyor. Fakat bazen Struct mı yoksa Class mı kullanayım sorusu kafa karıştırıcı olabiliyor. İşte tam bu noktada bu iki veri tipi arasındaki farka ve nerelerde kullanabileceğimize gelin birlikte bakalım.

Class Nedir?

Swift içerisinde farklı veri tiplerini bir arada tutabilmenizi sağlayan bir veri yapısıdır. Referans tiplidir(reference type). Yani bir ‘Class’ nesnesi başka bir değişkene atandığında veya bir fonksiyona parametre olarak geçirildiğinde referansı kopyalanır. Bu yüzden bir ‘Class‘ nesnesini değiştirirseniz, onu referans alan diğer değişkenlerde bu değişimden etkilenecektir. Peki Class nasıl oluşturulur ve kullanılır?


class Car {
   var brand : String
   var year : Int
   var color : String

   init(brand : String, year : Int, color : String) {
       self.brand = brand
       self.year = year
       self.color = color
   }

}

var myCar = Car(brand: "Porsche", year: 2024, color: "Black")

Struct Nedir?

Struct’ta aslında temel olarak Class gibi farklı veri tiplerini bir arada tutabilmenizi sağlayan bir veri yapısıdır. Fakat değer tiplidir (value type). Yani bir ‘Struct’ nesnesi bir değişkene veya fonksiyona parametre olarak geçirildiğinde kopyalanır. Bu sayede basit veri modelleri oluşturabilir, yaşam döngüsü içerisinde kolayca yönetebilirsiniz. Peki Struct nasıl oluşturulur ve kullanılır?


struct Car {
   var brand : String
   var year : Int
   var color : String
}

var myCar = Car(brand: "Porsche", year: 2024, color: "Black")

Kısaca Farklarına Bakacak Olursak

ClassStruct
Referans Tip (Reference Type)Değer Tip (Value Type)
Kalıtım (Inheritance) kullanılabilirKalıtım (Inheritance) kullanılamaz
Bellek öbek (Heap) olarak ayrılırBellek yığın (Stack) olarak ayrılır
Varsayılan olarak değiştirilebilir (Mutable)Varsayılan olarak değiştirilmez (Immutable)

Referans Tip ve Değer Tip

Aslında Struct ve Class veri tiplerini tanımlarken bu konuya biraz değinmiştik. Yakından bakacak olursak eğer;


Struct

  • Struct değer tiptir. Yani bir Struct’tan yeni bir örnek oluşturduğunuzda verilerin bir kopyasıyla çalışırsınız.
  • Yapacağınız değişiklik sadece üzerinde çalıştığınız örnek için geçerli olur. Diğer örnekleri etkilemez.
  • Başka bir değişkene veya fonksiyona parametre olarak aktarıldıklarında kopyalanırlar.

struct Car {
   var brand : String
   var year : Int
   var color : String
}

var myCar = Car(brand: "Porsche", year: 2024, color: "Black")
var mySecondCar = myCar

mySecondCar.color = "Blue"

print(myCar.color) //Black çıktısı alınır

Class

  • Class’lar referans tiptir. Yani bir Class’ın örneğini oluşturduğunuzda bellekte örneğe atanmış bir referansla çalışırsınız.
  • Oluşturacağınız birden fazla örnek aynı referansı işaret edebilir. Bu yüzden bir örnek için yapacağınız değişiklik diğer örnekler içinde geçerli olur.
  • Bir değişkene veya fonksiyona parametre olarak aktarıldıklarında referans yapısı dikkate alınmalıdır.

class Car {
   var brand : String
   var year : Int
   var color : String

   init(brand : String, year : Int, color : String) {
       self.brand = brand
       self.year = year
       self.color = color
   }

}

var myCar = Car(brand: "Porsche", year: 2024, color: "Black")
var mySecondCar = myCar

mySecondCar.color = "Blue"

print(myCar.color) //Blue çıktısı alınır

Kalıtım

Nesne yönelimli programlamanın temel taşlarından biri olan kalıtım, aslında adından da anlaşılacağı üzere özellik aktarımına yarar. Fakat Swift ile programlama yapıyorsanız bu kavramı yalnızca Class ile kullanabilirsiniz. Oluşturacağınız bir temel sınıfa ek olarak bir veya daha fazla alt sınıf ile hiyerarşiler oluşturmaya olanak tanır. Bu sayede alt sınıflar ana sınıfın özelliklerini ve yöntemlerini miras alabilir. Ayrıca oluşturacağınız bu yapı ile bir diğer nesne yönelimli programlama ilkesi olan çok biçimliliğe (polymorphism) kapı açabilirsiniz. Fakat vurguladığımız gibi bu özellikleri sadece Class ile kullanabilirsiniz. Çünkü oluşturulan her Struct tamamen bağımsızdır. Bu yüzden kalıtımı desteklemez.


Burada dikkat edilmesi gereken bir diğer nokta ise protokollerdir (Protocol). Bir protokolün Class’a ve Struct’a uygulanma şekli kalıtıma çok benzesede bu işlem kalıtım değildir. Burada aslında Class ve Struct, protokol tarafından belirlenen kuralı uygulamak zorunda olduğunu belirtir.


class Car {
    
   var brand : String
   var year : Int
   var color : String

   init(brand : String, year : Int, color : String) {
       self.brand = brand
       self.year = year
       self.color = color
   }

}

class Mercedes : Car {
    
    var model : String = ""
    
    func carDetail() {
        print("Car Detail : \(year) \(color) \(brand) \(model)")
    }

}

var myMercedes = Mercedes(brand: "Mercedes", year: 2024, color: "Black")
myMercedes.model = "CLS"
myMercedes.carDetail() //Car Detail : 2024 Black Mercedes CLS çıktısı alınır

Bellek Yönetimi

Bellek yönetimi Struct ve Class arasında seçim yapmak istediğinizde karşınıza çıkan bir diğer kritik nokta olabilir. Bu iki veri tipinin sahip olduğu yapısal fark, bellek yönetimi konusunda da farklılıklara neden olabiliyor. Yakından bakacak olursak eğer;


Struct

  • Struct değer (value) tipli olduğu için bellekte yığın (stack) olarak tutulur. Bu sayede daha küçük veri türleri için yüksek performans sağlanır.
  • Struct örnekleri sonlu yaşam döngülerine sahiptir. Yani kullanım sona erdiğinde otomatik olarak bellekten ayrıştırılır.
  • Sınırlı yaşam döngüsü ve değer tipi olması nedeniyle Struct ile ARC(Otomatik Referans Sayma) kullanılmaz.

Class

  • Class referans (reference) tipli olduğu için bellekte öbek (heap) olarak tutulur. Bu sayede daha büyük ve karmaşık yapıların kurulumuna izin verilir.
  • Class örnekleri oluşturuldukları kapsam ötesine uzanan yaşam sürelerine sahiptir. Bu uzun yaşam döngüsü nedeniyle, kontrolünün manuel gerçekleştirilmesi gerekir.
  • Manuel referans takibi için Swift içerisinde ARC(Otomatik Referans Sayımı) kullanılır. Bu yapı bir Class örneğinde kaç adet referans olduğunu takip eder ve kullanım durumuna göre bellekten ayrıştırılmasını sağlar. Bu sayede bellek yönetimi sağlanmış olur.

Değiştirilebilirlik

Bir diğer kritik tercih nedenlerinden biri olan değiştirilebilirlik, Struct ve Class veri tiplerinin yine birbirinden ayrışmasına neden oluyor. İncelemek istersek eğer;


Struct

  • Struct özellikleri ‘let’ ile bildirildiklerinde varsayılan olarak sabit olur ve değiştirilemezler. Ancak ‘var’ anahtar kelimesi ile belirlenen özellikler değiştirilebilir.
  • Bu durum oluşturduğunuz veri modeli için güvenlik ve değişmezlik sağlar.

struct Car {
    
   var brand : String
   var year : Int
   var color : String
    
}

let myCar = Car(brand: "Porsche", year: 2024, color: "Black")
var myCar2 = Car(brand: "Mercedes", year: 2024, color: "Red")

myCar.brand = "Mercedes" // {Cannot assign to property: 'myCar' is a 'let' constant} Hatası alınır
myCar2.year = 2023 // Hata alınmaz

Class

  • Class özellikleri, ‘let’ ve ‘var’ anahtar kelimelerine bakılmaksızın değiştirilebilir.
  • Bu esneklik Class örneğinde daha kolay değişiklik yapılabilmesini sağlar.

class Car {
    
   var brand : String
   var year : Int
   var color : String

   init(brand : String, year : Int, color : String) {
       self.brand = brand
       self.year = year
       self.color = color
   }

}

let myCar = Car(brand: "Porsche", year: 2024, color: "Black")

var myCar2 = Car(brand: "Mercedes", year: 2024, color: "Red")

myCar.brand = "Mercedes"
myCar2.year = 2023

print(myCar.brand) // {Mercedes} yazdırılır
print(myCar2.year) // {2023} yazdırılır

Ayrıca oluşturduğunuz veri modeli içinde yer alan bir özelliği bir metot ile değiştirmek istediğinizde Class ile kolayca yapabiliyorken Struct ile yapamazsınız. Struct ile çalışıyor ve içerisindeki bir özelliği değiştirmek istiyorsanız, yazacağınız metot ile birlikte ‘mutating’ anahtar kelimesini kullanmalısınız.


class Car {
    
   var brand : String
   var year : Int
   var color : String

   init(brand : String, year : Int, color : String) {
       self.brand = brand
       self.year = year
       self.color = color
   }
    
    func changeYear (newYear : Int) {
        self.year = newYear
        print("Updated Car Details : \(year) \(color) \(brand)")
    }

}

let myCar = Car(brand: "Porsche", year: 2024, color: "Black")

myCar.changeYear(newYear: 2023) 

//{Updated Car Details : 2023 Black Porsche} yazdırılır
struct Car {
    
    var brand : String
    var year : Int
    var color : String
    
    mutating func changeYear (newYear : Int) {
        self.year = newYear
        print("Updated Car Details : \(year) \(color) \(brand)")
    }
    
}

var myCar = Car(brand: "Porsche", year: 2024, color: "Black")

myCar.changeYear(newYear: 2023)

// {Updated Car Details : 2023 Black Porsche} yazdırılır

Ne Nerede Kullanılmalı?

İki veri tipi arasında seçim yapmak aslında tam olarak doğru değil. Çünkü bu durum projenizin bağlamına ve özel gereksinimlerine bağlıdır. Fakat yine basitçe değerlendirmemiz gerekirse;


Struct

  • Basit özelliklere sahip basit veri modelleri oluşturulmak istendiğinde
  • Oluşturulan nesnelerin birbirinden bağımsız olması istendiğinde
  • Güçlü değişmezlik özelliği ile kod güvenliğinin artırılması istendiğinde
  • Değer tipi sayesinde maksimum bellek performansına ulaşılmak istendiğinde

Class

  • Karmaşık özelliklere ve hiyerarşilere sahip veri modelleri oluşturulmak istendiğinde
  • Kalıtım ve çok biçimlilik uygulanmak istendiğinde
  • Referans tipi sayesinde paylaşılabilir ve kolay güncellenebilen verilerin oluşturulması istendiğinde
  • Referans sayımı ile kaynakların yönetilmesi istendiğinde

Struct ve Class arasındaki farklara baktığınız zaman aslında bu iki veri tipi arasında yapacağınız seçimin keyfi olmayacağını anlayabilirsiniz. Çünkü iki veri tipide kendince güçlü özelliklere sahip durumda. Burada vereceğiniz karar belirttiğimiz gibi tamamen yaptığınız projenin bağlamına, büyüklüğüne, karmaşıklığına ve gereksinimlerine bağlıdır. Bu iki veri tipi arasındaki farkı anlamak, verimli, sürdürülebilir ve ölçeklenebilir Swift projeleri oluşturmanıza olanak tanır. Doğru veri tipi ile oluşturacağınız projeler en iyi performansı gösterecek ve sizi başarıya ulaştıracaktır.

İnternet sitesi https://synta-x.com
Yazı oluşturuldu 30

Benzer yazılar

Aramak istediğinizi üstte yazmaya başlayın ve aramak için enter tuşuna basın. İptal için ESC tuşuna basın.