structure vs class in swift language

Swift

Swift Problem Overview


From Apple book "One of the most important differences between structures and classes is that structures are always copied when they are passed around in your code, but classes are passed by reference."

Can anyone help me understand what that means? To me, classes and structs seem to be the same.

Swift Solutions


Solution 1 - Swift

Here's an example with a class. Note how when the name is changed, the instance referenced by both variables is updated. Bob is now Sue, everywhere that Bob was ever referenced.

class SomeClass {
    var name: String
    init(name: String) {
        self.name = name
    }
}

var aClass = SomeClass(name: "Bob")
var bClass = aClass // aClass and bClass now reference the same instance!
bClass.name = "Sue"

println(aClass.name) // "Sue"
println(bClass.name) // "Sue"

And now with a struct we see that the values are copied and each variable keeps it's own set of values. When we set the name to Sue, the Bob struct in aStruct does not get changed.

struct SomeStruct {
    var name: String
    init(name: String) {
        self.name = name
    }
}

var aStruct = SomeStruct(name: "Bob")
var bStruct = aStruct // aStruct and bStruct are two structs with the same value!
bStruct.name = "Sue"

println(aStruct.name) // "Bob"
println(bStruct.name) // "Sue"

So for representing a stateful complex entity, a class is awesome. But for values that are simply a measurement or bits of related data, a struct makes more sense so that you can easily copy them around and calculate with them or modify the values without fear of side effects.

Solution 2 - Swift

Both class and structure can do:

  • Define properties to store values
  • Define methods to provide functionality
  • Be extended
  • Conform to protocols
  • Define initializers
  • Define Subscripts to provide access to their variables

The only class can do:

  • Inheritance
  • Typecasting
  • Define deinitialisers
  • Allow reference counting for multiple references.

Solution 3 - Swift

struct are value types. It means that if you copy the instance of the structure to another variable, it's just copied to the variable.

Example for Value Type

struct Resolution {
    var width = 2
    var height = 3
}

let hd = Resolution(width: 1920, height: 1080)
var cinema = hd //assigning struct instance  to variable
println("Width of cinema instance is \(cinema.width)")//result is 1920
println("Width of hd instance is \(hd.width)")//result is 1920

cinema.width = 2048

println("Width of cinema instance is \(cinema.width)")//result is 2048
println("Width of hd instance is \(hd.width)")//result is 1920

Classes are reference types. It means that if you assign an instance of the class to a variable, it will hold only the reference to the instance and not the copy.

Solution 4 - Swift

Above answers are correct I hope my answer will help someone who doesn't understand above answers.

Well in Swift There are two types of objects

  1. Struct
  2. Class

Main difference between them is

  • Struct is value type
  • Class is reference type

For example here code to understand well.

struct SomeStruct {
var a : Int;

init(_ a : Int) {
    self.a = a
}
}

class SomeClass {
var a: Int;

init(_ a: Int) {
    self.a = a
}

}
var x = 11

var someStruct1 = SomeStruct(x)
var someClass1 = SomeClass(x)

var someStruct2 = someStruct1
var someClass2 = someClass1

someClass1.a = 12
someClass2.a // answer is 12 because it is referencing to class 1     property a

someStruct1.a = 14
someStruct2.a // answer is 11 because it is just copying it not referencing it

This was main difference but we have also sub differences.

Class

  1. Must declare initialiser (constructer)
  2. Has deinitialisers
  3. Can inherit from other classes

Struct

  1. It has free initialiser for you , you dont have to declare initaliser if you do free initialiser will be overwritten by your declared initialiser
  2. Dont have deinitialiser
  3. Cannot inherit from other struct

Solution 5 - Swift

This question seems to be duplicate but regardless, the following would answer most of the use case:

  1. One of the most important differences between structures and classes is that structures are value types and are always copied when they are passed around in your code, and classes are reference type and are passed by reference.

  2. Also, classes have Inheritance which allows one class to inherit the characteristics of another.

  3. Struct properties are stored on Stack and Class instances are stored on Heap hence, sometimes the stack is drastically faster than a class.

  4. Struct gets a default initializer automatically whereas in Class, we have to initialize.

  5. Struct is thread safe or singleton at any point of time.

And also, To summarise the difference between structs and classes, it is necessary to understand the difference between value and reference types.

  1. When you make a copy of a value type, it copies all the data from the thing you are copying into the new variable. They are 2 separate things and changing one does not affect the other.
  2. When you make a copy of a reference type, the new variable refers to the same memory location as the thing you are copying. This means that changing one will change the other since they both refer to the same memory location. The sample code below could be taken as reference.

// sampleplayground.playground

  class MyClass {
        var myName: String
        init(myName: String){
            self.myName = myName;
        }
    }
    
    var myClassExistingName = MyClass(myName: "DILIP")
    var myClassNewName = myClassExistingName
    myClassNewName.myName = "John"
    
    
    print("Current Name: ",myClassExistingName.myName)
    print("Modified Name", myClassNewName.myName)
    
    print("*************************")
    
    struct myStruct {
        var programmeType: String
        init(programmeType: String){
            self.programmeType = programmeType
        }
    }
    
    var myStructExistingValue = myStruct(programmeType: "Animation")
    var myStructNewValue = myStructExistingValue
    myStructNewValue.programmeType = "Thriller"
    
    print("myStructExistingValue: ", myStructExistingValue.programmeType)
    print("myStructNewValue: ", myStructNewValue.programmeType)

Output:

Current Name:  John
Modified Name John
*************************
myStructExistingValue:  Animation
myStructNewValue:  Thriller

Solution 6 - Swift

Swift types

https://i.stack.imgur.com/pWLyB.png" height="300" />

>Value type is a type whose value is copied when it’s assigned to a variable or constant, when it’s passed to a function or when it's returned from function. (Also as and is checks make a copy of struct)

>Reference types are not copied when they are assigned to a variable or constant, or when they are passed to a function

Value Type:

Struct, Enum[About], Tuple
struct String, struct Array(Set, Dictionary)

(Objective-C int...)

String, and build-in collections value types contain internal reference to heap to manage it's size

  • When you assign or pass value type a new copy of data is created. The copy on write - COW mechanism is used for some specific classes(like Collections(Array, Dictionary, Set))[About] with some optimisations, for example the copy is created when object is modified. For custom types you should support COW by yourself
  • When you modify an instance it has only local effect.
  • Usually The Stack Memory is used[About]

Reference Type:
Class, Function

(Objective-C all others)

ARC is used

  • When you assign or pass reference type a new reference to original instance will be created(the address of instance is copied).
  • When you modify an instance it has a global effect because the instance is shared and accessible by any reference that points on it.
  • Usually The Heap Memory is used[About]

enter image description here

Value type is recommended to use by default. The biggest advantage of Value type is that usually they are thread safe

Reference type Pros:

  • they can be inherited,
  • deinit() can be used,
  • compare instances by reference ===,
  • Objective-C interoperability because Value Type was introduced in Swift.

[Stack vs Heap]
[let vs var, class vs struct]
[Class vs Structure]

Choosing Between Structures and Classes
Types
Classes And Structures

Solution 7 - Swift

If you look farther in the apple handbook you will see this section: “Structures and Enumerations Are Value Types”

In this section you will see this:

> “​let​ ​hd​ = ​Resolution​(​width​: ​1920​, ​height​: ​1080​) ​var​ > ​cinema​ = ​hd This example declares a constant called hd and sets it > to a Resolution instance initialized with the width and height of full > HD video (1920 pixels wide by 1080 pixels high). > > It then declares a variable called cinema and sets it to the current > value of hd. Because Resolution is a structure, a copy of the existing > instance is made, and this new copy is assigned to cinema. Even though > hd and cinema now have the same width and height, they are two > completely different instances behind the scenes. > > Next, the width property of cinema is amended to be the width of the > slightly-wider 2K standard used for digital cinema projection (2048 > pixels wide and 1080 pixels high): > > ​cinema​.​width​ = ​2048 Checking the width property of cinema shows > that it has indeed changed to be 2048: > > ​println​(​"cinema is now ​(​cinema​.​width​)​ pixels wide"​) ​// > prints "cinema is now 2048 pixels wide However, the width property of > the original hd instance still has the old value of 1920: > > println​(​"hd is still ​(​hd​.​width​)​ pixels wide"​) // prints "hd > is still 1920 pixels wide” > > When cinema was given the current value of hd, the values stored in hd > were copied into the new cinema instance. The end result is two > completely separate instances, which just happened to contain the same > numeric values. Because they are separate instances, setting the width > of cinema to 2048 doesn’t affect the width stored in hd.” > > Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. > https://itun.es/us/jEUH0.l

This is the biggest difference between structs and classes. Structs are copied and classes are referenced.

Solution 8 - Swift

Usually (in most programming languages), objects are blocks of data that are stored on heap, and then a reference (normally a pointer) to these blocks, contains a name is using to access these blocks of data. This mechanism allows sharing objects in the heap by copying the value of their references (pointers). This is not the case of basic data types such as Integers, and that is because the memory needed to create a reference is almost the same as the object (in this case integer value). Thus, they will be passed as values not as a reference in the case of large objects.

Swift uses struct in order to improve the performance even with String and Array objects.

A really good reading here

Solution 9 - Swift

Here is an example that shows the difference between struct and class precisely.

screenshot of written code in playground
screenshot of written code in playground

struct Radio1{
    var name:String
    //    init(name:String) {
    //        self.name = name
    //    }
}

struct Car1{
    var radio:Radio1?
    var model:String

}

var i1 = Car1(radio: Radio1(name:"murphy"),model:"sedan")
var i2 = i1
//since car instance i1 is a struct and 
//this car has every member as struct ,
//all values are copied into i2

i2.radio?.name //murphy
i2.radio = Radio1(name: "alpha")
i2.radio?.name //alpha

i1.radio?.name //murphy

//since Radio1 was struct , 
//values were copied and thus
// changing name  of instance of Radio1 in i2 
//did not bring change in i1

class Radio2{
    var name:String
    init(name:String) {
        self.name = name
    }
}

struct Car2{
    var radio:Radio2?
    var model:String

}
var i3 = Car2(radio: Radio2(name:"murphy"),model:"sedan")
//var radioInstance = Radio2(name: "murphy")
//var i3 = Car2(radio: radioInstance,model:"sedan")

var i4 = i3
//since i3 is instance of struct
//everything is copied to i4 including reference of instance of Radio2
//because Radio2 is a class



i4.radio?.name //murphy
i4.radio?.name="alpha"
i4.radio?.name //alpha

i3.radio?.name //alpha

//since Radio2 was class, 
//reference was copied and 
//thus changing name of instance 
//of Radio2 in i4 did  bring change in i3 too


//i4.radio?.name
//i4.radio = Radio2(name: "alpha")
//i4.radio?.name
//
//i3.radio?.name

Solution 10 - Swift

In order to understand the difference between Structs and Classes, we need to know the main difference between value and reference types. Structs are value types and that means that every change on them will just modify that value, Classes are reference types and every change in a reference type will modify the value allocated in that place of memory or reference. For example:

Let's start with a Class, this class conforms to Equatable just to be able to compare instances, we create an instance called pointClassInstanceAand other called pointClassInstanceB we assign class A to class B, now the assertion says that they are the same...

class PointClass: Equatable {
    var x: Double
    var y: Double
    
    init(x: Double, y: Double) {
        self.x = x
        self.y = y
    }
    
    static func == (lhs: PointClass, rhs: PointClass) -> Bool {
        return lhs.x == rhs.x && lhs.y == rhs.y
    }
}

var pointClassInstanceA = PointClass(x: 0, y: 0)
var pointClassInstanceB = pointClassInstanceA

assert(pointClassInstanceA==pointClassInstanceB) 

pointClassInstanceB.x = 10
print(pointClassInstanceA.x)
//this prints 10

Ok, what happened here why if we just changed the x value of pointsClassInstanceB it also changed the x value of pointClassInstanceA? well, this shows how reference types work, when we assign the instance A, as a value of instance B and then we modify X of one of them it will change both X's because they share the same reference and what changed was the value of that reference.

Let's do the same but with a struct

struct PointStruct: Equatable {
    var x: Double
    var y: Double
    
    init(x: Double, y: Double) {
        self.x = x
        self.y = y
    }
    
    static func == (lhs: PointStruct, rhs: PointStruct) -> Bool {
        return lhs.x == rhs.x && lhs.y == rhs.y
    }
}
var pointStructInstanceA = PointStruct(x: 0, y: 0)
var pointStructInstanceB = pointStructInstanceA

assert(pointStructInstanceA==pointStructInstanceB)
pointStructInstanceB.x = 100
print(pointStructInstanceA.x)
//this will print 0

We have basically the same structure as our class but now you can see that when you print the x value of pointStructInstanceA this case it didn't change, and this is because value types work differently and every change on one of their instances will be "independent" and will not affect the other.

Swift suggests to use more value types and you can tell that their libraries are based on structs to avoid the issues that reference types bring, like unintentionally modify a value etc. Structs are the way to go on Swift. Hope it helps.

Solution 11 - Swift

1.structure is value type.
   = > when we assign structure variable to other variable or pass as parameter to function, it creates separate/new copy => so that changes made on one variable does not  reflect on another.[We can say like **call by value** concept] 
Example :

    struct DemoStruct 
    { 
    	var value: String 
    	init(inValue: String) 
    	{ 
    		self.value = inValue 
    	} 
    } 

 
var aStruct = DemoStruct(inValue: "original") 
var bStruct = aStruct // aStruct and bStruct are two structs with the same value! but references to diff location`enter code here`
bStruct.value = "modified" 
 
print(aStruct.value) // "original" 
print(bStruct.value) // "modified"


2.class is reference type.
 = > when we assign structure variable to other variable or pass as parameter to function, it **does not** creates separate/new copy => so that changes made on one variable does not  reflect on another.[We can say like **call by reference** concept] 
Example:
class DemoClass 
{ 	
	var value: String 
	init(inValue: String) 
	{
		self.value = inValue 
	} 
} 
 
var aClass = DemoClass(inName: "original") 
var bClass = aClass // aClass and bClass now reference the same instance! 
bClass.value = "modified" 
 
print(aClass.value) // "modified" 
print(bClass.value) // "modified"

Solution 12 - Swift

Alreday there is a lot written about this, i would like to add a analogy there. Hope you will never have doubt in mind after this: Bottom line: classes are passed by reference whereas structs are passed by value.

Suppose you are sharing a google doc sheet with your friend. Now if he changes anything in that, you will also see that changes on your google doc, means your copy is also affected. That’s basically "passed by reference".

But suppose, if you have a .XLS fie saved in your machine. You provide that file give to your friend. Now if he is making any change in that file, your file will not be messed up/effected because you have your own copy. That's basically "passed by value". You have multiple simple programs already there to check this analogy in swift playgrounds.

Solution 13 - Swift

As many have already pointed out the differences in copying structs and classes, it can all be understood from where they come from in c, a struct like

struct A {
    let a: Int
    let c: Bool
}

in memory local to the func parent object or struct it will be something like

64bit for int
8 bytes for bool

now for

class A {
    let a: Int
    let c: Bool
}

instead of the contents of the data being stored in local memory or struct or class it will be a single pointer

64bit address of class A instance

When you copy the two its easy to see why there are difference, copy the first, you copy the 64bit for the int and the 8 bit for the bool, copy the second you copy the 64bit address to the instance of class A, you can have multiple copies of the same memory address, all pointing to the same instance, but each copy of the struct will be its own copy.

Now things can get complicated because you can mix the two you have to something like

struct A {
    let a: ClassA
    let c: Bool
}

your memory will look something like

64bit address of class A instance
8 bytes for bool

This is a problem because even though you have multiple copies of the struct in your program, they all have a copy to the same object ClassA, this means just like multiples reference to instance ClassA you pass around have to have a reference count kept of how many reference to the object exists to know when to delete them, you program can have multiple references to struct A that need to keep a reference count to their ClassA instances, this can be time consuming if your struct has a lot of classes in them, or the structs it contains has lots of classes in them, now when you copy your struct, the compiler has to generate code that goes through every single class instance referenced in your struct and substructs, and increment there reference count to keep track of how many references there are. This can make classes much faster to pass around as you just need to copy its single address, and it won't need to increase the reference count of any of its children because it want reduce the reference count of any child it contains until its own reference count reaches 0.

The thing gets even more complicated with some Apple struct types, that they actually have object types in them, the good thing about data that is reference to, is it can be stored in memory and be lengthened and contractor at will and they can be very large, unlike data stored on local stack, so types like String, Array, Set, Dictionary though they act like struct and will even make a duplicate of there internal data if you try to modify them so you don't change all occurrence, there data still has to be reference counted and so a struct containing a lots of these types can still be slow, because the internal data for each one has to be retained.

Of cause passing struct types can reduce the possibility of lots of error, but they can also slow your program down depending on the types the contain.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionManish AgrawalView Question on Stackoverflow
Solution 1 - SwiftAlex WayneView Answer on Stackoverflow
Solution 2 - SwiftDurul DalkanatView Answer on Stackoverflow
Solution 3 - Swiftashok vadiveluView Answer on Stackoverflow
Solution 4 - SwiftdaraView Answer on Stackoverflow
Solution 5 - SwiftDILIP KOSURIView Answer on Stackoverflow
Solution 6 - SwiftyoAlex5View Answer on Stackoverflow
Solution 7 - SwiftStuart CasarottoView Answer on Stackoverflow
Solution 8 - SwiftWilliam KinaanView Answer on Stackoverflow
Solution 9 - Swiftrahul vermaView Answer on Stackoverflow
Solution 10 - SwiftJames RochabrunView Answer on Stackoverflow
Solution 11 - SwiftSudhir BhagatView Answer on Stackoverflow
Solution 12 - SwiftASPView Answer on Stackoverflow
Solution 13 - SwiftNathan DayView Answer on Stackoverflow