Structures and classes are the basic building blocks of the program’s code.
They have properties and functions.
We can define a structure or class in a single file, the external interface of that structure or class is automatically made for other code to use.
The common things:
- Define properties to store values
- Define methods to provide functionality
- Define subscripts to provide access to their values using subscript syntax
- Define initializers to set up their initial state
- Be extended to expand their functionality beyond a default implementation
- Conform to protocols to provide standard functionality of a certain kind
The additional capabilities that classes support:
- Inheritance enables one class to inherit the characteristics of another.
- Type casting enables you to check and interpret the type of a class instance at runtime.
- Deinitializers enable an instance of a class to free up any resources it has assigned.
- Reference counting allows more than one reference to a class instance.
Usages
Definition
struct Cat {
var weight = 3
var legCount = 4
}
class Dog {
var weight = 5
var legCount = 4
var cloth = Cloth() // Every dog has a cloth in red color.
var name = String?
}
class Cloth {
var color = "red"
var width = 15
var length = 45
}
Create Instance
let cat = Cat()
let dogA = Dog()
let dogB = Dog()
let cloth = Cloth()
Access Properties
print(cat.legCount)
print(dogA.legCount)
print(dogB.cloth.color)
Initialize
class Dog {
var weight: Int
var legCount: Int
init (){
self.weight = 5
self.legCount = 4
}
init (weight: Int, legCount: Int = 4){
self.weight = weight
self.legCount = legCount
}
}
let dog = Dog(weight: 8)
print(dog.weight) // 8
print(dog.legCount) // 4
Structures and Enumerations Are Value Types
Value type will be copied the whole value when it’s being assigned.
integers, floating-point numbers, Booleans, strings, arrays and dictionaries are value types. They are implemented as structures behind the scenes.
Collections like String, array, dictionary use an optimization to reduce the performance cost of copying. They aren’t been copied immediately when be assigned. It creates a reference and share the memory of the collection, collection just be copied when the modification occurs.
Value Copy
let count = 4
let legCount = count // value copy
struct Rect {
var width = 20
var height = 10
}
var window = Rect()
// It's value copy, even the 'window' and the 'table' has the same width and height, they are two different instance of Rect.
var table = window
table.width = 25
print(table.width) // Print: 「25」
print(window.width) // Print: 「20」. It hasn't affect the width of the window.
enum Color: Int{
case green = 1, red, blue, white
mutating func toWhite() {
self = .white
}
}
var windowColor = Color.blue
let tableColor = windowColor // value copy
windowColor.toWhite()
print(windowColor) // white
print(tableColor) // blue
Classes Are Reference Types
Swift just copy the reference of the instance when assigned an instance to another one.
Reference Copy
class Dog {
var age = 2
}
let labulado = Dog()
let pet = labulado // Just copy the reference.
pet.age += 1 // The reference has't change, just change the property 'age' of the instance.
print(labulado.age) // 3
The labulado
and pet
are different reference, but they share one instance of the Dog
.
Identity Operators
- identical to (===)
- not identical to (!==)
Use identity operators to check whether two constants or variables refer to the same single instance.
if labulado === pet {
print("Refer to the same instance")
} else {
print("Refer to different instance")
}
Equal Operators
- equal to (==)
- not equal to (!=)
The basic value type can use the equal operators directly.
var s = "dd"
var a = "dd"
print(s == a)
We must define the equal function for our own customs classed and structures, before we use the equal operators.
class Dog {
var age = 2
// The equal function(operator override)
static func == (left: Dog, right: Dog) -> Bool {
return left.age == right.age
}
}
let pet = Dog()
pet.age += 1
let myPet = Dog()
myPet.age = 3
print(pet === myPet) // false, they are refer to different instance of Dog
print(pet == myPet) // true, here use the equal function above to check whether two instances are equal.
Pointer
The reference in Swift is similar to a pointer in C, but isn’t a direct pointer to an address in memory.
The standard library provides pointer and buffer types that we can use if we want to interact with pointer directly.