Video Coming Soon...
11: Basic Syntax: Functions
WARNING This exercise is in DRAFT status, so there may be errors. If you find any, please email me at help@learncodethehardway.com so I can fix them.
You are now ready to learn another fundamental building block of programming: the function. A function is:
- A block of code...
- With a name (or sometimes anonymous)...
- And variables to configure it...
- That can return new variables to use.
You've been using functions this whole time when you print text to the screen:
fmt.Println("See? Like this.")
In this exercise you'll learn how to make your own functions so you can keep your code organized and easy to understand.
How to Make a Function
You need 6 things to create a function:
- The keyword
func
- A name like
PrintStuffNow
orprint_stuff_now
- A set of parenthesis
(
and)
- Possible variables inside the
()
and their types. - A block of code to run inside
{
and}
- A possible
return
with a value or variable to give something back to the caller of this function.
Here's an example of all 6 things:
func PrintName(name string) string {
fmt.Println("Your name is", name)
return "done"
}
Let me break down every part of that first line so you know what it does:
func
-- Starts your function.PrintName
-- The name of the function.(
-- Starts the list of variables (aka parameters) for this function.name
-- The first variables names (aka parameter) and there can be as many as you want separated by,
(comma).string
-- The type for the variablename
and it can be any type you want.)
-- End the list of parameters for the function.string
-- This is the return value type of the function. If you need multiple values then you use()
similar to parameters. For example, to return 2int
I'd write(int, int)
.{
-- The start of your function body.
You don't need all of the features at once, only use what's needed. For example, this is also a function:
func something() {
fmt.Println("something")
}
There's even situations when you need to use a function without a name (called an anonymous function):
func () { fmt.Println("John Cena") }
These come in to play later when you pass functions to other functions, but that's an advanced topic for now.
How to Use Your Functions
You've already been using functions when you use fmt.Println("hi")
but you haven't used functions that return values yet. First, you use a function by "calling" it, and that's done by putting ()
(parenthesis) after its name:
PrintName("Zed")
You also have to include any parameters (that's the variables listed inside the ()
) the function needs.
The PrintName
function above though also returns a value, and to receive that you only need to assign it to a variable like you would with a number or a string:
is_done := PrintName("Zed")
fmt.Println(is_done)
This would print out "done" if you ran it because the PrintName
function uses return "done"
to give a variable/value back to the caller. The "caller" is any place in your code that calls another function.
How a Function Works
A function acts as a block of code that your main code jumps to temporarily. While the function's code is executing it will use its own set of variables so they don't impact your main code's variables. This is very important because you want your functions to run no matter where they are used, and if they changed other code you couldn't do that. Here's a function that does mostly nothing to demonstrate:
func DoNothing() {
a := 1
}
func main() {
a := 100
DoNothing()
fmt.Println(a)
}
This is what happens when this code runs:
- Your
main()
function is the entry point, so you program starts there. main()
first create a variable namea
with a value of100
.main()
then callsDoNothing()
, which makesmain()
the "caller".- Go then jumps to the line where
fund DoNothing()
is defined so it can run that code. - Inside
DoNothing()
it sets the variablea
to 1, however this is a totally different variable nameda
that does NOT change the one inmain()
. - When the
{
at the end ofDoNothing()
is reached Go jump back to themain()
right after its call toDoNothing()
. - At that point the
fmt.Println(a)
line runs, which will print out100
and NOT1
.
Functions, Variables, and return
A final piece of the function puzzle is that you can place a variable anywhere you place a function with a return
and vice-versa. For example, if you have this code:
x := Add(1, 2)
y := Sub(x, 3)
Then you could also write:
y := Sub(Add(1, 2), 2)
It's not a very nice thing to write though as the second form is difficult to understand, but it does come up in some functions you use. I use this in the code for this exercise so you have some experience translating the two styles.
The Code
Here's an example that uses functions to do some basic math.
View Source file ex11/main.go Only
package main
import (
"fmt"
)
func Add(a float64, b float64) float64 {
return a + b
}
func Sub(a float64, b float64) float64 {
return a - b
}
func Mul(a float64, b float64) float64 {
return a * b
}
func Div(a float64, b float64) float64 {
return a / b
}
func main() {
result := Add(Sub(3,4), Mul(10, Div(200, 10)))
fmt.Println("The result is:", result)
}
As usual, type it in gradually and get it to work slowly. You might need to enter each function before creating the main()
since main()
needs the other functions.
The Breakdown
func Add(a float64, b float64) float64 {
-- Creates a function nameAdd
that takes tofloat64
variables and returns afloat64
result.return a + b
-- Add the two numbers and returns the result.}
-- End of function.func Sub(a float64, b float64) float64 {
-- Same asAdd
, but this will do subtraction.return a - b
-- Subtracts the two numbers and returns the result.}
-- End of function.func Mul(a float64, b float64) float64 {
-- Same asAdd
andSub
, but it will multiply them.return a * b
-- Multiplies the two numbers and returns the result.}
--func Div(a float64, b float64) float64 {
-- Once again, but division.return a / b
-- Divides the two numbers and returns the result.}
-- End of function.func main() {
-- Your main function, where Go starts your program.result := Add(Sub(3,4), Mul(10, Div(200, 10)))
-- The formula. Figure it out.fmt.Println("The result is:", result)
-- Printing the result of the formula.}
-- End of main.
NOTE It's important to know that you could name these functions anything, and as long as you kept the functions' blocks the same they would work the same. If you don't believe me name them after fruit and watch how they work the same. It's very important you understand this as later you'll run into weird programmers like me who name their functions something strange for fun.
The Practice
- Break It -- There are many ways to break this one. Try calling functions without parameters, calling the wrong functions, misspelling the function names, using the wrong variables inside the functions, and more.
- Change It -- The most important thing you can do is convert this heinous string of nested functions into separate variables as mentioned previously.
- Remake It -- As usual, write a description the recreate it from memory using the description. The more you do this, the better you'll get.
Study Drills
- Use these functions to do even more math.
- Write more functions that do more math. Maybe a modulus function?
- Write some more functions that take
int64
instead. How do they compare to thefloat64
versions.
Register for Learn Go the Hard Way
Register today for the course and get the all currently available videos and lessons, plus all future modules for no extra charge.