Write a closure that accepts string and return length of string(which is integer) :
let simpleClosure:(String) -> (Int) = { name in
return name.count
}
let result = simpleClosure("Hello World")
print(result)
Write a closure that accepts string and return length of string(which is integer) :
let simpleClosure:(String) -> (Int) = { name in
return name.count
}
let result = simpleClosure("Hello World")
print(result)
Declaration:
var normalArray = [Int]() // declaring an empty Int array like this
var normalArray = [2,3,4,5]
var normalArray: [Int] = [2,3,4,5]
You also can declare an array with some repeated values or using one or more arrays
var normalArray = Array(repeating: 1, count: 3) //initialize normalArray with three ones var normalArray = arrayOne + arrayTwo //initialize normalArray with addign arrayOne & arrayTwo
normalArray.append(12) //append element at the end of array
normalArray += [100.0] //append at the endnormalArray.insert(12, at: 0) //insert element at 0 position. This position value should be n to n-1 if array have n number of elements.
normalArray[2] //return second element from array
normalArray.count // return the number of elements in array
normalArray.isEmpty // return false if array is empty
normalArray.capacity // return the number of elements in arraynormalArray.first //get the first element from array
normalArray.last //get the last elements from array
normalArray.max() //get the max element from array
normalArray.min() //get the min element from arraynormalArray.sorted() // sort the array
normalArray.reversed() //reverse an array
normalArray.shuffled() //shuffle the elements of an array
normalArray[2] = 1 // replace the value in second index of arraynormalArray[1...3] = [12, 23, 34] // set first to third position value as 12, 23 &34
normalArray.removeAll() // remove allelement from array
normalArray.removeFirst() // remove first element from array
normalArray.removeLast() // remove last element from arraynormalArray.remove(at: 2) //remove second element from arraynormalArray.removeLast(1) // remove the second element from the end index of arraynormalArray.removeFirst(2) // remove the thirdelement from the start index of the array
for i in 0..<normalArray.count{
print(normalArray[i])
}or
for item in normalArray{
print(item)
}
var normalDictionary = [Int: String]()
// an empty "normalDictionary" with Int type key & String type value
var normalDictionary = [1: "John", 2: "Doe"]
var normalDictionary : [Int: String] = [1: "John", 2: "Doe"]
normalDictionary[3] = "Mihalos" // Add a value "Mihalos" for key "3"
normalDictionary[2] //return the value of second key-value pair in dictionary normalDictionary.count // return the number of elements in dictionarynormalDictionary.isEmpty // return false if dictionary is emptynormalDictionary.capacity // return the number of elements in dictionarynormalDictionary.first //get the first element from dictionarynormalDictionary.max { a, b in a.value < b.value} // return key-value pair for maximum valuenormalDictionary.min() { a, b in a.value < b.value} // return key-value pair for minimumvaluenormalDictionary.sorted( by: { $0.0 < $1.0 }) // reurn an sorted array of dictionarynormalDictionary.reversed() //return key-value pair in reverse ordernormalDictionary.shuffled() //shuffle the key-value pair of dictionary
normalDictionary[3] = "Mike"
normalDictionary.updateValue("Duke", forKey: 3)
normalDictionary[3] = nil // remove key-value pair for key "3"
normalDictionary.removeAll() // remove all element from dictionary arraysimpleDictionary.removeAll(keepingCapacity: true) remove all elements with keeping the capacity or not
for (key, value) in normalDictionary {
print(key, value)
}
Instead of key-value pair we also can access only key or value from dictionary like this
for key in normalDictionary.keys{
print(key)
}for value in normalDictionary.values{
print(value)
}
We also can get the keys and values of a dictionary as an array.
let keys = [Int](normalDictionary.keys) // return all the keys as an array
let values = [String](normalDictionary.values) //return all the values as an array
var normalSet = Set<Int>() // an empty Int type set
var normalSet = Set([10, 20, 30, 40, 20])
varnormalSet: Set<String> = ["John", "Doe", "Hi", "John"]
You also can declare a set with some repeated values but you will get a single value for those repeated value cause set didn’t store any duplicate element.
var normalSet = Set(repeatElement(1, count: 3)) // Initialize set with three ones but set will have only one into it.
normalSet.insert(12) // //append element at the end of set
normalSet.contains(2) // check an element is in the set or not
normalSet.count // return the number of elements in set
normalSet.isEmpty // return false if set is empty normalSet.capacity // return the number of elements in setnormalSet.first //get the first element from set
normalSet.max() //get the max element from set
normalSet.min() //get the min element from setnormalSet.sorted() // sort the set
normalSet.reversed() // reverse set
normalSet.shuffled() // shuffle set elements
normalSet.removeFirst() // remove first element from set
normalSet.remove(1) // remove from a specific indexnormalSet.removeAll() // remove all elements from set
normalSet.removeAll(keepingCapacity: true) // remove all elements with keeping the capacity or not
for data in normalSet {
print(data)
}
The set type didn’t have any order so if you want to traverse in any order you can do it by swift provided methods
for data in normalSet.sorted() {
print(data)
}for data in normalSet.reversed() {
print(data)
}
normalSet2.union(normalSet3).sorted() // perform union opertion within normalSet2 & normalSet3
normalSet2.intersection(normalSet3) // perform intersection within two set
normalSet2.subtracting(normalSet3) // perform subtracting
normalSet2.symmetricDifference(normalSet3) // perform symmetricDifferencenormalSet2.isSubset(of: normalSet3) // check one set is subset of snother or not
normalSet2.isSuperset(of: normalSet3) // check superset or not
normalSet2.isDisjoint(with: normalSet3) // check disjoint or not
A value type instance is an independent instance and holds its data in its own memory allocation. There are a few different value types: Struct, Enum, Tupple.
Let’s experiment with struct
and prove that they’re value types:
Add the following code to your playground:
// 1
struct Car {
let brand: String
var model: String
}
// 2
var golf = Car(brand: "Volkswagen", model: "Golf")
// 3
let polo = golf
// 4
golf.model = "Golf 2019"
// 5
print(golf)
print(polo)
In the code above, you will:
Car
struct with brand
and model
properties.Car
named golf
.golf
instance, named polo
.golf.model
variable to Golf 2019
print
statement prints Car(brand: "Volkswagen", model: "Golf 2019")
in the Console. The second one prints Car(brand: "Volkswagen", model: "Golf")
. Even if polo
is a copy of golf
, the instances remain independent with their own unique data copies.With this simple playground, we’ve confirmed that structs
are indeed value types.
To check that enums
are value types, add this code to the playground:
// 1
enum Language {
case italian
case english
}
// 2
var italian = Language.italian
// 3
let english = italian
// 4
italian = .english
// 5
print(italian)
print(english)
In the code above, you will:
Language
enum with italian
and english
cases.Language
for the italian
language.italian
instance, named english
.italian
instance to english
.print
statement prints english
, and the second one prints italian
. Even if english
is a copy of italian
, the instances remain independent.The last value type that we'll explore is tuple
. A tuple type is a comma-separated list of zero or more types, enclosed in parentheses. You can access its values using the dot (.
) notation followed by the index of the value.
You can also name the elements in a tuple and use the names to access the different values.
Add the following code to the playground:
// 1
var ironMan = ("Tony", "Stark")
// 2
let parent = ironMan
// 3
ironMan.0 = "Alfred"
// 4
print(ironMan)
print(parent)
In the code above, you will:
ironMan
tuple with the strings Tony
and Stark
.ironMan
instance, named parent
.ironMan.0
index to Alfred
.print
, prints ("Alfred", "Stark")
and the second one, prints ("Tony", "Stark")
. Again, the instances remain independent.You can now be certain that structs
, enums
, and tuples
are value types!
Use value types when comparing instance data with ==
makes sense.==
checks if every property of the two instances is the same.
With value types you always get a unique, copied instance, and you can be sure that no other part of your app is changing the data under the hood. This is especially helpful in multi-threaded environments where a different thread could alter your data.
Use a value type when you want copies to have an independent state, and the data will be used in code across multiple threads.
In Swift, Array
, String
, and Dictionary
are all value types.
In Swift, reference type instances share a single copy of their data, so that every new instance will point to the same address in memory. A typical example is a class
, function
, or closure
.
To explore these, add a new function to your playground:
func address<T: AnyObject>(of object: T) -> Int {
return unsafeBitCast(object, to: Int.self)
}
This function prints the address of an object, which will help you check whether you're referencing the same instance or not.
The first reference type that you'll look at is a class
.
Add the following code to your playground:
// 1
class Dog: CustomStringConvertible {
var age: Int
var weight: Int
// 2
var description: String {
return "Age \(age) - Weight \(weight)"
}
// 3
init(age: Int, weight: Int) {
self.age = age
self.weight = weight
}
}
// 4
let doberman = Dog(age: 1, weight: 70)
// 5
let chihuahua = doberman
// 6
doberman.age = 2
// 7
chihuahua.weight = 10
// 8
print(doberman)
print(chihuahua)
// 9
print(address(of: doberman))
print(address(of: chihuahua))
In the code above, you will:
class
named Dog
, that conforms to CustomStringConvertible
to print the custom descriptions of the object.init
function. This is needed because, unlike a struct
, a class
doesn't automatically create an initialization function based on the variables of the object.doberman
instance of Dog
.doberman
, named chihuahua
.doberman.age
to 2
.chihuahua.weight
to 10
.print
, prints Age 2 - Weight 10
, and the second one prints the same; Age 2 - Weight 10
. This is because you're actually referencing the same object.print
statements print the same value.You can rest assured that a class
is a reference type.
A closure
is used to refer to a function along with the variables from its scope that it encapsulates. Functions are essentially closures that store references to variables in their context.
Take a look at the code below:
let closure = { print("Test") }
func function() -> (){ print("Test") }
closure()
function()
They both do the same thing.
You can find more info about closures in Swift's docs.
Use a reference type when comparing instance identity with ===
makes sense. ===
checks if two objects share the same memory address.
They’re also useful when you want to create a shared, mutable state.
As a general rule, start by creating your instance as an enum
, then move to a struct
if you need more customization, and finally move to class
when needed.