Reputation: 11026
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.
Upvotes: 212
Views: 95368
Reputation: 187034
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 its 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.
Upvotes: 501
Reputation: 34255
Swift types
named type
or nominal type
or type with name
compound type
or non-nominal type
or type without name
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. (Alsoas
andis
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
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 yourselfReference Type:
Class
, Function
(Objective-C all others)
ARC
is used
reference type
a new reference to original instance will be created(the address of instance is copied).Value type
is recommended to use by default. The biggest advantage of Value type
is that usually they are thread safe
Reference type
Pros:
deinit()
can be used,===
,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
Upvotes: 15
Reputation: 7435
Both class and structure can do:
The only class can do:
Upvotes: 68
Reputation: 6037
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.
Upvotes: 1
Reputation: 137
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"
Upvotes: 1
Reputation: 465
This question seems to be duplicate but regardless, the following would answer most of the use case:
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.
Also, classes have Inheritance which allows one class to inherit the characteristics of another.
Struct properties are stored on Stack and Class instances are stored on Heap hence, sometimes the stack is drastically faster than a class.
Struct gets a default initializer automatically whereas in Class, we have to initialize.
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.
// 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
Upvotes: 11
Reputation: 88
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.
Upvotes: 0
Reputation: 39
Here is an example that shows the difference between struct and class precisely.
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
Upvotes: 1
Reputation: 4377
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 pointClassInstanceA
and 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.
Upvotes: 1
Reputation: 763
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
Main difference between them is
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
Struct
Upvotes: 12
Reputation: 28799
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.
Upvotes: 3
Reputation: 503
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.
Upvotes: 36
Reputation: 1187
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.
Upvotes: 3