Day 5 of 100 Days of SwiftUI
Tags: swift, swiftui, beginners
Published: 2020-01-19 22:51:50

#Introduction

This is the fifth day of learning [SwiftUI](https://developer.apple.com/xcode/swiftui/) using [Paul Hudson](https://twitter.com/twostraws)'s [100 Days of SwiftUI challenge](https://www.hackingwithswift.com/100/swiftui). 

Today I learned how to write re-usable code using a function.

#Summary
<ul>
  <li>
    <strong id ="loop">Function</strong> - Repeating code is a bad idea, functions helps us avoid doing that.
  </li>
</ul>
``` swift
// Declaring a function
func readMe() {
    let text = """
        Welcome to our application

        We love making beautiful apps!
    """
    print(text)
}

// Calling the function
readMe()

// You can send values to a function. These values are called parameters. You tell Swift the type of data it must be
// Here we're telling the function to expect to receive two floats called base and height
func areaOfTriangle(base: Float, height: Float) {
    let result = 0.5 * base * height
    print("The area of a triangle is: \(result)")
}

areaOfTriangle(base : 7.0, height : 2.0)

// Swift allows us to provide two names for each parameter. One to be used externally when calling the function, while the other one is used internally respectively. It helps to give the variable a sensible name inside and outside the function
func areaOfTriangle2(base b: Float, height h: Float) {
    let result = 0.5 * b * h
    print("The area of a triangle is: \(result)")
}

areaOfTriangle2(base : 3.0, height : 4.0)

// Swift allows us to omit parameter labels by using underscore (_) for external parameter name but generally, it is better to give parameters external names to avoid confusion
func sayHello(_ name : String) {
    print("Welcome, \(name)")
}

sayHello("Kehinde")

// You can send back data from a function. You will specify the kind of data to be returned. The return keyword is required inside the declared function
//Instead of printing out the output, we'll return a value
func areaOfRectangle(length: Float, breadth: Float) -> Float {
    return length * breadth
}

areaOfRectangle(length : 10.0, breadth : 5.0)

// Default parameters
func welcome(to name: String = "Africa") {
    print("Welcome, \(name)")
}

// This will print "Welcome, Africa"
welcome()
// This will override the default value to print "Welcome, Las Vegas"
welcome(to : "Las Vegas")
```

<ul>
  <li>
    <strong id ="variadic function">Variadic function</strong> - You can make any parameter variadic by writing ... after its type. This means that there are zero or more integers, and Swift converts the value passed into an array of integers.
  </li>
</ul>
``` swift
func square(numbers : Int...) {
    for number in numbers {
        print("\(number) squared is: \(number * number)")
    }
}
// runing the function with some numbers seperated by commas
square(numbers: 8,3,2,4,1)
```

<ul>
  <li>
    <strong id ="">Writing throwing functions</strong> - Writing throwing functions - Swift allows us throw errors from functions by marking them as throws before their return type. It uses the throw keyword when something goes wrong. The first step is to define an enum that describes the error we'd like to throw. It must be based on Swift's existing Error type.
  </li>
</ul>
``` swift
// example
enum PasswordError: Error {
    case obvious
}

func checkUserPassword(_ password: String) throws -> Bool {
    if password == "iamapassword" {
        throw PasswordError.obvious
    }
    return true
}

```
<ul>
  <li>
    <strong id ="">Running throwing functions</strong> - You need to call these functions using three (3) keywords. (1) <strong>do</strong> - starts a section of code that might cause problems (2) <strong>try</strong> - it is used before every function that might throw an error (3) <strong>catch</strong> - lets you handle the error gracefully. If error are thrown inside a do block, execution jumps to the catch block immediately.
  </li>
</ul>
``` swift
do {
    try checkUserPassword("iamapassword")
    print("This will not print")
} catch {
    print("This will be printed instead")
}
```

<ul>
  <li>
    <strong id ="">inout functions</strong> </li> All parameters in a swift function are constant, you can't change them. inout allows us change parameters in a function and those changes reflect in the original value outside of the function. <strong>I still find this concept a little confusing</strong>
</ul>
``` swift
// original valariable outside the function
var myOriginalVariable = 30

// print myVariable
print("myOriginalVariable is \(myOriginalVariable)")

// This directly changes the value directly rather than returning a new one
func doubleTheNumber(number : inout Int) {
    number *= 2
}

// The ampersand (&) makes it an explicir=t recognition that you're aware that it is being used as inout
// This outputs 60
doubleTheNumber(number: &myOriginalVariable)
```

Thanks for reading🙏🏿.

You can find me on Twitter [@RealKennyEdward](https://twitter.com/RealKennyEdward)

I'm on to Day6!