< How many parameters should a function accept? | How can you return two or more values from a function? > |
Updated for Xcode 15
We use the return
keyword to send back values from functions in Swift, but there is one specific case where it isn’t needed: when our function contains only a single expression.
Now, “expression” isn’t a word I use often, but it’s important to understand here. When we write programs we do things like this:
5 + 8
Or this:
greet("Paul")
These lines of code get resolved to a single value: 5 + 8 gets resolved to 13, and greet("Paul")
might return a string “Hi, Paul!”
Even some longer code will get resolved to a single value. For example, if we had three Boolean constants like this:
let isAdmin = true
let isOwner = false
let isEditingEnabled = false
Then this line of code would resolve to a single value:
isOwner == true && isEditingEnabled || isAdmin == true
That would become “true”, because even though isOwner
is false, isAdmin
is true, so the whole expression becomes true.
So, lots of code we write can be resolved to a single value. But there’s also a lot of code that can’t be resolved to a single value. For example, what’s the value here:
let name = "Otis"
Yes, that creates a constant, but it doesn’t become a value in its own right – we couldn’t write return let name = "Otis"
.
Similarly, we write might take actions like this:
if name == "Maeve" {
print("Hello, Maeve!")
print("How are you?")
}
That also can’t become a single value, because it has two function calls in there.
Now, all this matters because these divisions have names: when our code can be boiled down to a single value, such as true, false, “Hello”, or 19, we call that an expression. Expressions are things that can be assigned to a variable, or printed using print()
. On the other hand, when we’re performing actions such as creating variables, starting a loop, or checking a condition, then we call that a statement.
All this matters because Swift lets us skip using the return
keyword when we have only one expression in our function. So, these two functions do the same thing:
func doMath() -> Int {
return 5 + 5
}
func doMoreMath() -> Int {
5 + 5
}
Remember, the expression inside there can be as long as you want, but it can’t contain any statements – no new variables, and so on.
Swift is really smart here, and will automatically allow us to use simple if
and switch
values in much the same way – as long as they return values directly rather than trying to create new variables, etc.
For example, this is allowed:
func greet(name: String) -> String {
if name == "Taylor Swift" {
"Oh wow!"
} else {
"Hello, \(name)"
}
}
A string is returned directly from both parts of that condition, so it's allowed. However, this is not allowed:
func greet(name: String) -> String {
if name == "Taylor Swift" {
"Oh wow!"
} else {
let greeting = "Hello, \(name)"
return greeting
}
}
That attempts to create a new greeting
constant before returning it.
Internally what's happening here is that if
is able to become an expression in its own right, as long as each branch of the if
– each possible result it can produce – is itself a single expression.
This allows us to assign the result of a condition directly to a new value, which looks a little odd at first:
func greet(name: String) -> String {
let response = if name == "Taylor Swift" {
"Oh wow!"
} else {
"Hello, \(name)"
}
return response
}
That's usually a little hard to understand at first, but try to think of it like a ternary conditional operator:
func greet(name: String) -> String {
let response = name == "Taylor Swift" ? "Oh wow!" : Hello, \(name)"
return response
}
SPONSORED 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! Hurry up because it'll be available only until April 28th.
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.