Let’s play with swift-part 1

Rejaul Hasan
6 min readJul 4, 2021

This is not a language learning article. In daily life coding I often forget so many topics and tricks which are useful to use in live project. So this lockdow I think to brush-up some of my skills and this time make my own document. So that, I can get back to it easily. I planned to brush-up swift, c++, basic data structures and algorithms, some advance DS and ALGO, important design patterns and testing. So, now started with swift. I use this book and apple provided book. It was for my personal use but letter think to share with the community. So, please do not expect a nice explaining article. It may help someone to brush up their skills also. I divided swift into 4–5 part. This is the first part. So, let’s start.

find the error from below code.

2 + 6   // OK
2 + 6 // OK
2 +6 // ERROR
2+ 6 // ERROR

last 2 line give error. The errors are.

1. Consecutive statements on a line must be separated by ';'
2.'+' is not a postfix unary operator
  1. show 1st error because xcode take it as a 2 statement(2; +6). So it say to use ; for separating 2 statements.
  2. in 2+ 6 the 2 statement are 2+ and 6. Here + is used as a postfix unary operator of 2. So it give that error.

Shift operations

1 << 3    left shift 1 at 3 times and output will be 8.
32 >> 2 right shift binary of 32 at 2 times output will be 8.

Type conversion

var integer: Int = 100
var decimal: Double = 12.5
integer = decimal

The above code give error. Swift does not support autometic implicit type conversion like c++ or other languages.

integer = Int(decimal)

Above one compile because it explicitly cast the value into integer.

let hourlyRate: Double = 19.5
let hoursWorked: Int = 10
let totalCost: Double = hourlyRate * hoursWorked

Not compile, because multiplication operate on 2 different types of data.

which data type it will cast?

let stringDog = "D"

stringDog will cast as a string not as a chracter. Swift take single character as string by default. So to cast as a character you should not depend on type inference. You need to explicitly cast it, as a character.

let stringDog: String

Multi-line strings

let data = """
it's a miltiline
string.
"""

Tuple

let coordinates3D = (x: 2, y: 3, z: 1) // It's better to name each elements of the tuple.
let (x3, y3, z3) = coordinates3D // This way we can assign it at the same time.

if we do not want to assign all element then we can use underscore(_) to indicate the missing element which we do not want to read. see below.

let (x3, y3, _ ) = coordinates3D

Typealias

typealias Coordinates = (Int, Int)
let xy: Coordinates = (2, 4)

here coordinates actually is a tuple but it create’s a new type.

Let’s check some error

let character: Character = “Dog” 
let character: Character = “! “
let string: String = “Dog”
let string: String = “! “

Line 1 and 2 give error as it’s a string not character.

let tuple = (day: 15, month: 8, year: 2015)
let day = tuple.Day

The upper code will not compile as there is a spalling mistake Day.

let name = "Matt"
name += " Galloway"

let is constant type we can not change it’s value.

The ternary conditional operator

let result = condition ? assign this value if it true : assign this value if it false;

Repeat-while loops or do while loop

repeat {
<LOOP CODE>
} while <CONDITION>
var sum = 1
repeat {
sum = sum + (sum + 1)
} while sum < 1000

Countable ranges

countable closed range

let closeRange = 0...5

must have 3 dot and it print from 0 to 5. output = 0,1,2,3,4,5

A closed range can never be empty. Why?

Because a closed range includes its upper bound, a closed range whose lower bound is equal to the upper bound contains that value. Therefore, a ClosedRange instance cannot represent an empty range.

countable half-open range

let range = 0..<5

notice the 2 dot and a less than operator. It print 0 up to 5 excluding 5. Output = 0,1,2,3,4

for loop

1. for _ in 0..<count { code }  //loop over from 0 to count-1.2. for i in 1...count where i % 2 == 1 {
sum += i
}

BREAK, CONTINUE AND RETURN

Break stop the execution of inner most loop or immediate loop and start running the code after the loop. Continue stop execution only the condition is true and it do not stop the entire loop. Only stop that iteration and start executing from the next iteration.

We can manipulate this in swift. Have a look at below code.

sum = 0rowLoop: for row in 0..<8 {
columnLoop: for column in 0..<8 {
if row == column {
continue rowLoop
}
sum += row * column
}
}

Here we label the for loop and this continue actually stop that iteration of first loop(rowLoop) when the condition true and start running from the next iteration. This is called labeled statements.

You can use labeled statements like these with break to break out of a certain loop. Normally, break and continue work on the innermost loop, so you need to use labeled statements if you want to manipulate an outer loop.

Some Switch

let coordinates = (x: 3, y: 2, z: 5)
switch coordinates {
case (0, 0, 0): // 1
print("Origin")
case (_, 0, 0): // 2
print("On the x-axis.")
case (0, _, 0): // 3
print("On the y-axis.")
case (0, 0, _): // 4
print("On the z-axis.")
default: // 5
print("Somewhere in space")
}

Here the (_) means we don’t care about this value for this condition.

Function Advanced parameter handling

func incrementAndPrint(_ value: Int){
}

By default parameters are constant in a function. We can not change the value of them. It send a copy of actual variable. Call it as pass by value.

func incrementAndPrint(_ value: inout Int){
}

The above one are called pass by reference or copy in copy out. Here we send reference/address of the actual variable so what we change inside the function it will reflect the actual variable also.

func getValue() -> Int {31}func getValue() -> String {
"Matt Galloway"
}
let testValue = getValue()

Which function called here? Actually it provides an error because there is an ambiguity. You should call

let testValue: Int = getValue() or let testValue:String = getValue()

Only this way swift understand which method you called.

Functions as variables

We can assign function to a variable. suppose

func add(_ a:Int, _ b:Int)->Int{ 
a+b
}
var function = add //The type is (Int, Int)->Int when you check it.
function(4,5) //result is 9

As function is just another type like Int, Double and string and we can assign it into a variable so we can pass it into a function as a parameter. So we are able to pass function as a parameter into another function.

func test(_ function:(Int,Int)->Int, _ a: Int, _ b: Int){
let result = function(a,b)
print(result)
}
// Call
test(add,4,5)

The land of no return

func infiniteLoop() -> Never {
while true {
}
}

This method never gets back to the place or scope where it is called. It will be useful if we want to process any data in the background until the app terminated by the user and also without notifying the user.

Commenting your functions

/// Calculates the average of three values
/// - Parameters:
/// - a: The first value.
/// - b: The second value.
/// - c: The third value.
/// - Returns: The average of the three values.
func calculateAverage(of a: Double, and b: Double, and c:
Double) -> Double {
let total = a + b + c
let average = total / 3
return average
}
calculateAverage(of: 1, and: 3, and: 5)

Instead of the usual double-/, you use triple-/ instead. Then the first line is the description of what the function does. Following that is a list of the parameters and finally a description of the return value.

Optional

var errorCode: Int?
let errorCode: Int?

errorCode is an “optional Int”. This means the variable itself is like a box containing either an Int or nil.

var optionalInt: Int? = 10
var mustHaveResult = optionalInt ?? 0

this is called nil coalescing. Here if optionalInt get nil then 0 will use as a default value.

.

--

--

Rejaul Hasan

I work as a Sr. software engineer for iOS platform. Available to discuss about any good opportunities or projects.