Swift ( Enums VS Structures VS Classes)

Saad El Oulladi
3 min readOct 4, 2018

--

Coming from an objective c background, the difference between components like enums, classes, and structs was quite obvious for me: An Enum is a set of named values, Struct is structured data type, and of course Class allows us to create objects with all POO related stuff.

When i first started learning Swift, it was a little confusing. Since sometime they may look similar. And Structs might be found in swift where only classes were used in some other languages.

  • For instance : Enums and Structs may also have methods or constructors.

Personally I needed some time to get familiar with the extended features we have with structs and enumerations in swift.

So in order to know where to use each one. it’s important to have a clear understanding of what makes one different from another. So let’s try to go over them one by one.

Reference types & Value types

The key difference between classes from one side, and enumerations and structures from another. Is that Classes are reference types, while enumerations and structures are value types .

Which means when you assign a class type object to an other. They become
pointing on the same instance. Hence when one is modified, the modification is applied to the other :

class Cat {   var name:String   init(name:String) {      self.name = name   }}var cat1 = Cat(name: "Kitty")var cat2 = cat1cat1.name = "Oscar"
// Both cats are the same
print("cat1 name : \(cat1.name), cat2 name : \(cat2.name)")
// cat1 name : Oscar, cat2 name : Oscar

while for structures and enumerations a new copy is created on every assignment :

struct Cat {var name:String}var cat1 = Cat(name: "Kitty")var cat2 = cat1cat1.name = "Oscar"print("cat1 name : \(cat1.name), cat2 name : \(cat2.name)")
//cat1 name : Oscar, cat2 name : Kitty

Mutability

The fact that structs and enums are values types, has some other side effects apart from assignment.

When a Structs is created as a constant (using let) , the whole instance is immutable. Which means we are not allowed to modify its properties :

struct Cat {    var name:String}let cat1 = Cat(name: "Kitty")cat1.name = "Oscar"// error: cannot assign to property

But for classes. Even when its a constant, only the reference is immutable. while the properties could be modified without issues :

class Cat {    var name:String?}let cat1 = Cat()cat1.name = "Oscar"// Working fine

Even when declared as a variable (var), a struct cannot modify itself. and to do so, we need to use mutating keyword. which is not available for classes :

struct Cat {   private var vaccinated:Bool   init() {      self.init()   }   // Will not work without mutating keyword   mutating func vaccinate() {      self.vaccinated = true   }}var cat1 = Cat()cat1.vaccinate()

Deinitializer

While having init method for both values and reference types. deinit method does not exist for value types. knowing that they are not concerned by reference counting :

struct Cat {   var name:String   deinit {   }}
// Compiler Error : Deinitializers may only be declared within a class

Generated init

An option possible only with structs. “Generated init methods” that are based on properties :

struct Cat {var name:Stringvar age:Int}let cat1 = Cat(name: "Lucy", age: 3)

Inheritance

Also note that only classes supports inheritance :

struct Pet {     var name:String}struct Cat : Pet {}
// ERROR : Inheritance from non-protocol type 'Pet'

Stored properties

Unlike Classes and Structs, an enum cannot contain a stored property :

enum Pet {

var name:String
// error: enums must not contain stored properties
}

Conclusion

Finally we can say that structs are used where we want to represent a data structure. Mainly models. While classes are used in most of other cases.

You can note also that structs are considered to be thread-safe. Due to their value type nature.

Thank you for reading. And I hope you found this useful 👍👍

--

--