Updated for Xcode 14.2
You’ve seen how to create functions and how to add parameters to them, but functions often also send data back – they perform some computation, then return the result of that work back to the call site.
Swift has lots of these functions built in, and there are tens of thousands more in Apple’s frameworks. For example, our playground has always had import Cocoa
at the very top, and that includes a variety of mathematical functions such as sqrt()
for calculating the square root of a number.
The sqrt()
function accepts one parameter, which is the number we want to calculate the square root of, and it will go ahead and do the work then send back the square root.
For example, we could write this:
let root = sqrt(169)
print(root)
If you want to return your own value from a function, you need to do two things:
return
keyword to send back your data.For example, perhaps you want to roll a dice in various parts of your program, but rather than always forcing the dice roll to use a 6-sided dice you could instead make it a function:
func rollDice() -> Int {
return Int.random(in: 1...6)
}
let result = rollDice()
print(result)
So, that says the function must return an integer, and the actual value is sent back with the return
keyword.
Using this approach you can call rollDice()
in lots of places across your program, and they will all use a 6-sided dice. But if in the future you decide you want to use a 20-sided dice, you just need to change that one function to have the rest of your program updated.
Important: When you say your function will return an Int
, Swift will make sure it always returns an Int
– you can’t forget to send back a value, because your code won’t build.
Let’s try a more complex example: do two strings contain the same letters, regardless of their order? This function should accept two string parameters, and return true if their letters are the same – so, “abc” and “cab” should return true because they both contain one “a”, one “b”, and one “c”.
You actually know enough to solve this problem yourself already, but you’ve learned so much already you’ve probably forgotten the one thing that makes this task so easy: if you call sorted()
on any string, you get a new string back with all the letters in alphabetical order. So, if you do that for both strings, you can use ==
to compare them to see if their letters are the same.
Go ahead and try writing the function yourself. Again, don’t worry if you struggle – it’s all very new to you, and fighting to remember new knowledge is part of the learning process. I’ll show you the solution in a moment, but please do try it yourself first.
Still here? Okay, here’s one example solution:
func areLettersIdentical(string1: String, string2: String) -> Bool {
let first = string1.sorted()
let second = string2.sorted()
return first == second
}
Let’s break that down:
areLettersIdentical()
.string1
and string2
.Bool
, so at some point we must always return either true or false.==
to compare the strings – if they are the same it will return true, otherwise it will return false.That code sorts both string1
and string2
, assigning their sorted values to new constants, first
and second
. However, that isn’t needed – we can skip those temporary constants and just compare the results of sorted()
directly, like this:
func areLettersIdentical(string1: String, string2: String) -> Bool {
return string1.sorted() == string2.sorted()
}
That’s less code, but we can do even better. You see, we’ve told Swift that this function must return a Boolean, and because there’s only one line of code in the function Swift knows that’s the one that must return data. Because of this, when a function has only one line of code, we can remove the return
keyword entirely, like this:
func areLettersIdentical(string1: String, string2: String) -> Bool {
string1.sorted() == string2.sorted()
}
We can go back and do the same for the rollDice()
function too:
func rollDice() -> Int {
Int.random(in: 1...6)
}
Remember, this only works when your function contains a single line of code, and in particular that line of code must actually return the data you promised to return.
Let’s try a third example. Do you remember the Pythagorean theorem from school? It states that if you have a triangle with one right angle inside, you can calculate the length of the hypotenuse by squaring both its other sides, adding them together, then calculating the square root of the result
You already learned how to use sqrt()
, so we can build a pythagoras()
function that accepts two decimal numbers and returns another one:
func pythagoras(a: Double, b: Double) -> Double {
let input = a * a + b * b
let root = sqrt(input)
return root
}
let c = pythagoras(a: 3, b: 4)
print(c)
So, that’s a function called pythagoras()
, that accepts two Double
parameters and returns another Double
. Inside it squares a
and b
, adds them together, then passes that into sqrt()
and sends back the result.
That function can also be boiled down to a single line, and have its return
keyword removed – give it a try. As usual I’ll show you my solution afterwards, but it’s important you try.
Still here? Okay, here’s my solution:
func pythagoras(a: Double, b: Double) -> Double {
sqrt(a * a + b * b)
}
There’s one last thing I want to mention before we move on: if your function doesn’t return a value, you can still use return
by itself to force the function to exit early. For example, perhaps you have a check that the input matches what you expected, and if it doesn’t you want to exit the function immediately before continuing.
SPONSORED From March 20th to 26th, you can join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer!
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.