Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Swift 4 Programming Cookbook

You're reading from   Swift 4 Programming Cookbook 50 task-oriented recipes to maximise Swift 4 productivity

Arrow left icon
Product type Paperback
Published in Sep 2017
Publisher Packt
ISBN-13 9781786460899
Length 384 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Keith Moon Keith Moon
Author Profile Icon Keith Moon
Keith Moon
Arrow right icon
View More author details
Toc

Table of Contents (9) Chapters Close

Preface 1. Swift Building Blocks FREE CHAPTER 2. Building on the Building Blocks 3. Data Wrangling with Swift Control Flow 4. Generics, Operators, and Nested Types 5. Beyond the Standard Library 6. Swift Playgrounds 7. Server-Side Swift 8. Performance and Responsiveness in Swift

Functions

Functions are a building block of almost all programming languages, allowing functionality to be defined and reused. Swift's syntax provides an expressive way to define your functions, creating concise and readable code.

How to do it...

Let's look at how functions are defined in Swift:

func nameOfFunction(parameterLabel1 parameter1: ParameterType1, parameterLabel2 parameter2: ParameterType2,...) -> OutputType { 

// Function's implementaion
// If the function has an output type,
// the function must return a valid value
return output
}

Let's look at this in more detail to see how a function is defined:

  • func : This indicates that you are declaring a function.
  • nameOfFunction : This will be the name of your function, and by convention is written in camel case (this means that each word, apart from the first, is capitalized and all spaces are removed). This should describe what the function does, and should provide some context to the value returned by the function, if one is returned. This will be how you will invoke the method from elsewhere in your code, so bear that in mind when naming it.
  • parameterLabel1 parameter1: ParameterType1 : This is the first input, or parameter, into the function. You can specify as many parameters as you like, separated by commas. Each parameter has a parameter name (parameter1) and type (ParameterType1); the parameter name is how the value of the parameter will be made available to your function's implementation. You can optionally provide a parameter label in front of the parameter name (parameterLabel1 ), which will be used to label the parameter when your function is used (at the call site).
  • -> OutputType : This indicates that the function returns a value and indicates the type of that value. If no value will be returned, this can be omitted. In the following code illustration, the curly brackets indicate the start and end of the function's implementation; anything within them will be executed when the function is called:
{  
// Function's implementaion
}
  • return output : If the function returns a value, you type return and then the value to return. This ends the execution of the function; any code written after the return statement is not executed.

Now, let's put this into action.

How it works...

Imagine that we are building a contacts app to hold the details of your family and friends, and we want to create a string of a contact's full name. Let's explore some of the ways functions can be used:

// Input parameters and output 
func fullName(givenName: String, middleName: String, familyName: String) -> String {
return "\(givenName) \(middleName) \(familyName)"
}

The preceding function takes three string parameters and outputs a string that puts all these together with spaces in between and returns the resulting string. The only thing this function does is take some inputs and produce an output without causing any side effects; this type of function is often called a pure function. To call this function, we enter the name of the function followed by the input parameters within () brackets, where each parameter value is preceded by its label:

let myFullName = fullName(givenName: "Keith", middleName: "David", familyName: "Moon") 
print(myFullName) // Keith David Moon

Since the function returns a value, we can assign the output of this function to a constant or a variable, just like any other expression:

// Input parameters, with a side effect and no output 
func printFullName(givenName: String, middleName: String, familyName: String) {
print("\(givenName) \(middleName) \(familyName)")
}

The next function takes the same input parameters, but its goal is not to return a value. Instead, it prints out the parameters as one string separated by spaces:

printFullName(givenName: "Keith", middleName: "David", familyName: "Moon") 

We can call this function in the same way as the preceding function, although it can't be assigned to anything since it doesn't have a return value:

// No inputs, with an output 
func authorsFullName() -> String {
return fullName(givenName: "Keith", middleName: "David", familyName: "Moon")
}

The preceding function takes no parameters as everything it needs to perform its task is contained within it, although it does output a string. This function calls the fullName function we defined earlier, taking advantage of its ability to produce a full name when given the component names; reusing is the most useful feature that functions provide:

let authorOfThisBook = authorsFullName()

Since authorsFullName takes no parameters, we can execute it by entering the function name followed by empty brackets (), and since it returns a value, we can assign the outcome of authorsFullName to a variable:

// No inputs, no ouput 
func printAuthorsFullName() {
let author = authorsFullName()
print(author)
}

Our final example takes no parameters and returns no value:

printAuthorsFullName()

You can call this function in the same way as the previous functions with no parameters, but there is no return value to assign.

As you can see from the preceding examples, having input parameters and providing an output value are not required when defining a function.

There's more...

Now, let’s look at a couple of ways to make your use of functions more expressive and concise.

Default parameter values

One convenience in Swift is that you can specify default values for parameters, which allows you to omit the parameter when calling. Let's take the preceding example situation, where we are creating a contact app to hold information about our family and friends. Many of your family members are likely to have the same family name as you, so you can set your family name as the default value for that parameter so that you only need specify the family name if it is different from the default.

Let's enter the following code into a playground:

func fullName(givenName: String, middleName: String, familyName: String = "Moon") -> String { 
return "\(givenName) \(middleName) \(familyName)"
}

Defining a default value looks similar to assigning a value to the familyName: String = "Moon" parameter. When calling the function, the parameter with the default value does not have to be given:

let keith = fullName(givenName: "Keith", middleName: "David") 
let alissa = fullName(givenName: "Alissa", middleName: "May")
let laura = fullName(givenName: "Laura", middleName: "May", familyName: "Jones")
print(keith) // Keith David Moon
print(alissa) // Alissa May Moon
print(laura) // Laura May Jones

Parameter overloading

Unlike Objective-C, Swift supports parameter overloading, which allows for functions to have the same name and only be differentiated by the parameters that they take.

Let's learn more about parameter overloading by entering the following code into a playground:

func combine(_ givenName: String, _ familyName: String) -> String { 
return "\(givenName) \(familyName)"
}

func combine(_ integer1: Int, _ integer2: Int) -> Int {
return integer1+integer2
}

let combinedString = combine("Finnley", "Moon")
let combinedInt = combine(5, 10)
print(combinedString) // Finnley Moon
print(combinedInt) // 15

Both the preceding functions have the name combine, but one takes two Strings as parameters and the other takes two Ints. Therefore, when we come to call the function, the compiler knows which implementation we intended by the values we pass as parameters.

We've introduced something new in the preceding function declarations--anonymous parameter labels, _ givenName: String.

When we declare the parameters, we use an underscore _ for the parameter label; this indicates that we don't want a parameter name shown when calling the function. This should only be used if the purpose of the parameters is clear without the labels, as is the case in the preceding example--combine("Finnley", "Moon").

See also

You have been reading a chapter from
Swift 4 Programming Cookbook
Published in: Sep 2017
Publisher: Packt
ISBN-13: 9781786460899
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at R$50/month. Cancel anytime