# Swift 5.3 - Section 1: Swift Basics

For this series of posts I have used extensively the book Swift Apprentice by Ray Wenderlich.
I strongly suggest this book, because if you buy the digital copy, Ray Wenderlich guarantees updates for the rest of the life!

The purpose of these post is not to copy the book itself, that I strongly suggest to read, also doing the suggested exercises, that give the required confidence to really learn the language.
In particular I will not explain how to use Xcode or the playgrounds. The idea is that you buy the book and read it!

Final note: my background is deep experience in C#, so maybe some concepts are obvious for me. If you read this article, find it useful, but would like that I add something, don't hesitate to comment here below! But remember, my goal is not to copy the book :-)

# Chapter 1: Expressions, Variables & Constants

``````// This is a comment. It is not executed.

/* This is also a comment.
Over many..
many...
many lines. */
``````

``````/* This is a comment.
/* And inside it
is
another comment.
*/

Back to the first.
*/
``````

## Print in the debug area

``````print("Hello, Swift Apprentice reader!")
``````

How to remove the new-line at the end, or how to finish the current line:

``````print("\(player), ", terminator: "") // no newline

print("") // print one final newline
``````

## The remainder operation

Between ints:

``````28 % 10
``````

Between decimal numbers:

``````(28.0).truncatingRemainder(dividingBy: 10.0)
``````

## Some math functions

``````max(5, 10)
// 10

min(-5, -10)
// -10

sin(45 * Double.pi / 180)
// 0.7071067811865475

cos(135 * Double.pi / 180)
// -0.7071067811865475

(2.0).squareRoot()
// 1.414213562373095

Int.random(in: 1...6)
``````

## Constants and variables

``````let number: Int = 10
var variableNumber: Int = 42
``````

Variables are block-scoped.

# Chapter 2: Types & Operations

## Type conversion

``````var integer: Int = 100
var decimal: Double = 12.5
integer = Int(decimal)
``````

## Type inference

In Xcode, you can analyze the type of a variable or constant with Option+Click on the name itself.

How to cast with type inference:

``````let actuallyDouble: Double = 3
let actuallyDouble: Double(3)
let actuallyDouble = 3 as Double
``````

## Characters and strings

``````let characterA: Character = "a"
let stringDog = "Dog" // Inferred to be of type String
``````

Interpolation:

``````message = "Hello my name is \(name)!" // "Hello my name is Matt!"
``````

Multi-line strings:

``````let bigString = """
You can have a string
that contains multiple
lines
by
doing this.
"""
print(bigString)
``````

## Tuples

``````let coordinates: (Int, Int) = (2, 3)
let x1 = coordinates.0
let y1 = coordinates.1
``````

Named tuples:

``````let coordinatesNamed = (x: 2, y: 3)
// Inferred to be of type (x: Int, y: Int)
let x2 = coordinatesNamed.x
let y2 = coordinatesNamed.y
``````

Deconstruction:

``````let coordinates3D = (x: 2, y: 3, z: 1)
let (x3, y3, z3) = coordinates3D
let (x4, y4, _) = coordinates3D
``````

## Type aliases

``````typealias Animal = String
let myPet: Animal = "Dog"

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

# Chapter 3: Basic Control Flow

## Bool toggling

``````var switchState = true
switchState.toggle() // switchState = false
switchState.toggle() // switchState = true
``````

## If statement

``````let hourOfDay = 12
var timeOfDay = ""

if hourOfDay < 6 {
timeOfDay = "Early morning"
} else if hourOfDay < 12 {
timeOfDay = "Morning"
} else if hourOfDay < 17 {
timeOfDay = "Afternoon"
} else if hourOfDay < 20 {
timeOfDay = "Evening"
} else if hourOfDay < 24 {
timeOfDay = "Late evening"
} else {
timeOfDay = "INVALID HOUR!"
}
print(timeOfDay)
``````

AND and OR conditions are short-circuited.

## While loops

``````var sum = 1

while sum < 1000 {
sum = sum + (sum + 1)
}
``````

## Repeat While loops

``````sum = 1

repeat {
sum = sum + (sum + 1)
} while sum < 1000
``````

# Chapter 4: Advanced Control Flow

## Countable ranges

``````let closedRange = 0...5
let halfOpenRange = 0..<5
``````

## For loops

``````let count = 10
var sum = 0
for i in 1...count {
sum += i
}
``````

Conditions in loops:

``````sum = 0
for i in 1...count where i % 2 == 1 {
sum += i
}
``````

## Continue to an outer loop

``````sum = 0

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

## Switch statements

``````switch hourOfDay {
case 0...5:
timeOfDay = "Early morning"
case 6...11:
timeOfDay = "Morning"
case 12...16:
timeOfDay = "Afternoon"
case 17...19:
timeOfDay = "Evening"
case 20..<24:
timeOfDay = "Late evening"
default: timeOfDay = "INVALID HOUR!"
}
``````

Condition on cases:

``````switch number {
case let x where x % 2 == 0:
print("Even")
default:
print("Odd")
}
``````

Pattern matching:

``````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")
}
``````

Pattern matching when capturing variables:

``````switch coordinates {
case (0, 0, 0):
print("Origin")
case (let x, 0, 0):
print("On the x-axis at x = \(x)")
case (0, let y, 0):
print("On the y-axis at y = \(y)")
case (0, 0, let z):
print("On the z-axis at z = \(z)")
case let (x, y, z):
print("Somewhere in space at x = \(x), y = \(y), z = \(z)")
}
``````

More complex example:

``````switch coordinates {
case let (x, y, _) where y == x:
print("Along the y = x line.")
case let (x, y, _) where y == x * x:
print("Along the y = x^2 line.")
default:
break
}
``````

# Chapter 5: Functions

## External names

Renaming an external name of a parameter:

``````func printMultipleOf(multiplier: Int, and value: Int) {
print("\(multiplier) * \(value) = \(multiplier * value)")
}

printMultipleOf(multiplier: 4, and: 2)
``````

Hiding an external name of a parameter:

``````func printMultipleOf(_ multiplier: Int, and value: Int) {
print("\(multiplier) * \(value) = \(multiplier * value)")
}

printMultipleOf(4, and: 2)
``````

Functions support default values.

## Return values

Return values:

``````func multiply(_ number: Int, by multiplier: Int) -> Int {
return number * multiplier
}

let result = multiply(4, by: 2)
``````

Return value with a tuple:

``````func multiplyAndDivide(_ number: Int, by factor: Int)
-> (product: Int, quotient: Int) {
return (number * factor, number / factor)
}

let results = multiplyAndDivide(4, by: 2)
let product = results.product
let quotient = results.quotient
``````

Removing the return value for single statement functions:

``````func multiply(_ number: Int, by multiplier: Int) -> Int {
number * multiplier
}

func multiplyAndDivide(_ number: Int, by factor: Int)
-> (product: Int, quotient: Int) {
(number * factor, number / factor)
}
``````

``````func getHighestGrade(for grades: Int...) -> Int {
}

``````

## Parameters passed by reference

``````func incrementAndPrint(_ value: inout Int) {
value += 1
print(value)
}

var count = 0
incrementAndPrint(&count)
``````

``````func printMultipleOf(multiplier: Int, andValue: Int)
func printMultipleOf(multiplier: Int, and value: Int)
func printMultipleOf(_ multiplier: Int, and value: Int)
func printMultipleOf(_ multiplier: Int, _ value: Int)
``````

## Functions as variables

Note that when passing a function as variable, the parameter names are not considered in the function signature.

``````func add(a: Int, b: Int) -> Int {
a + b
}

function(4, 2)
``````

Passing a function as a parameter to another function:

``````func printResult(_ function: (Int, Int) -> Int, _ a: Int, _ b: Int) {
let result = function(a, b)
print(result)
}

``````

## No return

``````func noReturn() -> Never {
}
``````

You can automatically comment a function in Xcode with Option-Command-/.

Sample of function declaration:

``````/// 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)
``````

## Closures

A closure is an anonymous method without parameter names.
A closure always require the return type, even if it is Void.

``````typealias Operate = (Int, Int) -> Int
let op: Operate = +

var addClosure: Operate = { (a: Int, b: Int) -> Int in
return a + b
}
``````

Shortening closure syntax:

``````let longClosure = { (a: Int, b: Int) -> Int in
a * b
}

let noParameterTypes: Operate = { (a, b) -> Int in
a * b
}

let noReturnType: Operate = { (a, b) in
a * b
}

let shortClosure: Operate = { \$0 * \$1 }
``````

Closures with Void return type:

``````let voidClosure: () -> Void = { () -> Void in
print("Test")
}

let voidClosure: () -> Void = {
print("Test")
}
``````

# Chapter 6: Optionals

## Optionals

``````var errorCode: Int?
errorCode = 100
errorCode = nil
``````

## Unwrapping

Force unwrapping:

``````var authorName: String? = "Matt Galloway"
var unwrappedAuthorName = authorName!
print("Author is \(unwrappedAuthorName)")
``````

Optional binding (plus shadowing, because the unwrapped variable name is the same as the optional name):

``````if let authorName = authorName {
print("Author is \(authorName)")
} else {
print("No author.")
}
``````

Multiple optional bindings (all the optionals must be not nil to enter the if statement):

``````if let authorName = authorName,
let authorAge = authorAge {
print("The author is \(authorName) who is \(authorAge) years old.")
} else {
print("No author or no age.")
}
``````

Combine multiple unwrapping with additional boolean checks:

``````if let authorName = authorName,
let authorAge = authorAge,
authorAge >= 40 {
print("The author is \(authorName) who is \(authorAge) years old.")
} else {
print("No author or no age or age less than 40.")
}
``````

## Introducing guard

Check of input parameters of functions (with guard, you have always to provide an else clause):

``````func guardMyCastle(name: String?) {
guard let castleName = name else {
print("No castle!")
return
}

// At this point, `castleName` is a non-optional String
print("Your castle called \(castleName) was guarded!")
}
``````

Example of another use:

``````func maybePrintSides(shape: String) {
guard let sides = calculateNumberOfSides(shape: shape) else {
print("I don’t know the number of sides for \(shape).")
return
}

print("A \(shape) has \(sides) sides.")
}
``````

## Nil coalescing

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