Swift Basics Part 3

Swift Basics Part 3

Welcome back! If you've been following my Swift Basics series so far, we have covered constants and variables, data types, and structs and classes. In this article, we will take a look at how to declare Functions in Swift. If you've read my previous posts, we are going to pick up where we left off with our Vehicle and Car classes. If you haven't been following along, check out my Swift Basics Part 2 post so you understand the starting point for this post. Let's get started!

Getting Started with Functions

What is a Function? A function allows programmers to group a specific set of instructions that they want to execute later. It may surprise you to hear this, but you've already used functions without even knowing! In my previous post, we used the print() function to display output from our Person and Car classes in the Debug window. The print() function is code that has already been created for us by the creators of the Swift language. That's all well and good, but we're not always going to have functions that do exactly what we want already created for us. We need a way to create our own functions. Add the following code to your existing Car class:

func honkHorn() {
    print("Beep beep!")
}

Your Car class should now look something like this:

class Car: Vehicle {
    var numberOfWheels: Int = 4

    func honkHorn() {
        print("Beep beep!")
    }
}

With just those 3 lines of code, you have created your first function! Creating a function is quite simple, you specify a name after the keyword func, add a set of () at the end of the name to indicate this function does not take any Parameters (more on this a little later), and use a set of {} to open and close the function. Simple, right? So what is this new function going to do? When the function is called it is going to print Beep beep! to the Debug window. Let's do that now. Add this line of code to the end of your playground file:

car.honkHorn()

Your playground file should now look something like this:

class Vehicle {
    let color: String
    let engine: String

    init(color: String, engine: String) {
        self.color = color
        self.engine = engine
    }
}

class Car: Vehicle {
    var numberOfWheels: Int = 4

    func honkHorn() {
        print("Beep beep!")
    }
}

let car = Car(color: "black", engine: "V8")
car.honkHorn()

The final line we have added to the file, car.honkHorn() tells Xcode that we want to call the honkHorn() method of our car instance. If you run the playground file, you should see Beep beep! has been printed in the Debug window.

Now, you may have noticed that I just referred to honkHorn() as a method. What does that mean? Let's take a quick detour and discuss Methods and Functions.

What is a Method?

It's worth talking a little bit about the distinction between a Function and a Method. What's the difference? In practical terms, nothing. A function is a method and a method is a function. There is no difference in how they are created, no difference in functionality, no special keywords or anything of the sort. What it boils down to is where the piece of code is created. If a function is created within a class or struct, like we have done with the honkHorn(), we refer to it as a Method. If not, we call it a Function. From what you have seen so far, we would refer to honkHorn() as a method and print() as a function. Don't get too hung up on this, the terms are regularly used interchangeably. Just know, if someone refers to methods when talking about Swift, that person is talking about functions within a class or struct.

Functions with Parameters

If we look at the method we created in our Car class, we can see that honkHorn() has a pair of empty parentheses after the method name. In Swift, if you are creating a function that does not require any input values, you can simply use the empty (). However, sometimes you will want to pass in values that your function can then use. For this next example, we are going to return to our Person struct (or class, doesn't matter what you have right now) and add a new method to it. Add this method to your Person struct:

func greet(person: String) {
    print("Hello there, \(name)!")
}

A couple new things going on here, so let's discuss piece-by-piece. Unlike our honkHorn() method that did not have any parameters, our new method, greet(person:), has one parameter that will accept a string value. When creating methods with parameters, you can add a parameter by specifying the parameter name and its type within the (). Within the method body, we are using the print() function to print out Hello there, \(person). So what does \(person) mean? What are we doing here? We are using a built-in piece of Swift functionality known as String Interpolation to use a placeholder that is going to be replaced by whatever value we enter for the person parameter. That argument is going to be the value we see printed to the Debug window once we call our function. Let's do that now so you can better understand what I mean. But before continuing, make sure your Person struct looks like this:

struct Person {
    let name: String
    let birthMonth: String
    var age: Int

    func greet(person: String) {
        print("Hello there, \(person)!")
    }
}

Now that your Person struct matches mine, add the following lines of code outside the last closing curly bracket of the Person struct:

let person = Person(name: "Robert", birthMonth: "February", age: 38)
person.greet(person: "Jeff")

Go ahead and run your playground. What do you see printed in the Debug window? You should see Hello there, Jeff!. In these couple lines we created a new instance of the Person struct called person, then we called the greet(person:) method and passed in the value Jeff as the argument.

And just like that, you now know how to create functions with parameters!

Returning Values from Functions

The last thing I would like to discuss in this post about functions is how to Return values from a function. There are many cases where, rather than simply printing to the Debug window, you actually want to get a value back from your function. When building an app, maybe you want to know how many rows to return in a table view (more on this in a future post, promise) or maybe you're working on a calculator and need to return the value of 4 * 5. To accomplish these kinds of tasks, we need functions that will return values. For this example, we are going to create a brand new function in our playground file. Add this function to the end of your file:

func calculateProduct(a: Double, b: Double) -> Double {
    return a * b
}

This looks really similar to functions we created before, right? For our new function we still:

  • declare the function with the keyword func
  • give the function a name
  • add parameters within the ()
  • use {} to open and close the function body.

When we create a function that is going to return some value, there are two differences we need to remember:

  1. Specify what type of value you want to return. The Return Type in this case is Double. We declare the return type using the -> Double.
  2. Use the keyword return to let Xcode know what should be returned from the function.

Now that we have our new function, let's test it out. Add calculateProduct(a: 5, b: 76.4) to the end of your playground file and check out what happens when you run it. You can see that the value is shown on the right side of the screen. If we leave this line as is, we are going to lose the result of our calculation. We need a way of storing the output of our function if we want to use it later. Any idea on how we can do that?

let product = calculateProduct(a: 5, b: 76.4)

If you said, "store the output of our function in a constant or variable," then you would be correct! Our new constant, product, now stores the output from our calculateProduct function. You can check that this is the case. Add print(product) to the end of your playground and run it. You should now see 382.0 printed to the Debug window.

Wrap Up

And there you have it! You can now create your own functions! Functions are super handy and make organizing your code much easier. If you want to learn even more about functions, check out the official Swift documentation. As always, I highly recommend that you play around with what you just learned. We already created a function that handles multiplication, but what about addition, subtraction, and division? Try creating functions that will handle each of those operations. The more you practice, the better you'll get.

Happy coding!