This week it's going to be all about functions as we dive deep into Golang’s semantics to enable you to write complex programs.
I pasted many code snippets from Golang’s reference manual, so credits to them.
Functions
First, you need to know what function declarations look like in Golang. Here is their schema:
func (VAR1 TYPE1, ...) NAME RETURN_TYPE {
/* body */
}
A few important things to note here:
- All functions are made with the
func
keyword - In golang, the variable names precede their types. This is also true inside function arguments.
- The name comes after the function signature.
- Finally, after the signature and name comes the return value.
So the order in which these elements appear may be opposite from what you're used to.
Also, functions can return a tuple containing more than one value like this:
func (VAR1 TYPE1, ...) NAME (RET_VAR1 RET_TYPE1, ...)
So inside the parentheses on the right, we have a tuple that contains not only the type of each item in the return value but also its name since there is more than one return value now.
Now, you might be wondering how you are going to reference multiple return values at once. The answer is, it is not much different from defining multiple return values. Specifically, it's done like this:
a, b, c = f(...)
The variables need to be written in the order the return values are. You can't mix up their order.
Essential Function Statements
You need to know a couple of statements to use functions effectively, such as conditionals, loops, and how to return from a function.
Conditionals
We have if
statements that test for arbitrary events and also switch
statements that compare a variable against several values.
In Golang, if
statements aren’t wrapped around parentheses and look like this:
if x > max {
x = max
}
They can also have an assignment before the condition. However, this is more of an aesthetic feature than a technical one because you could've done the same thing by writing the assignment before the entire if
statement.
if x := f(); x < y {
return x
} else if x > z {
return z
} else {
return y
}
Here I also showcase the use of else if
and a final else
clause.
Now let's cover the switch statement:
switch tag {
default: s3()
case 0, 1, 2, 3: s1()
case 4, 5, 6, 7: s2()
}
We can arrange the cases in any order we like and still achieve correct program execution. break
statements are not needed after each case, unlike in some other languages.
switch x := f(); { // missing switch expression means "true"
case x < 0: return -x
default: return x
}
Here we are testing the result of each expression in the case against the value “true” which is the default value to be tested when there's only an assignment in the switch statement like this.
switch {
case x < y: f1()
case x < z: f2()
case x == 4: f3()
}
The default “true” test subject also applies when the switch statement is empty, like this example.
Loops
We have two kinds of loop statements, and both of them use the for
keyword. The first kind contains only a conditional and is equivalent to “while” statements in other languages:
for a < b {
a *= 2
}
While the second kind of loop statement has an initiazation statement and a post-condition statement:
for i := 0; i < 10; i++ {
f(i)
}
Return statements
Finally, returning from a function is done using the return
statement. We can put a value after the return
keyword to return a value, which can also be a comma-separated list of values if you want.
Golang also has a break
statement that gets you out of a loop, and a continue
statement that jumps the program directly to the next loop iteration, skipping all the later statements in the loop in progress.
Essential packages
In Golang, functions are organized in packages and not stand-alone in the global scope. Here are some of the more essential modules you will be using:
fmt
math
os
regex
sort
strings
time
We will not cover these packages in extreme detail, but I’ll tell you what each module does and some of the more widely used functions in each.
fmt
The fmt
module contains functions to format a string with additional variables and print it to the console, a file, or a string. It also contains functions to read formatted input from these sources.
Among the functions it exports are Printf()
, Fprintf()
(print to file), Sprintf()
(print to string), Scanf()
, Fscanf()
, and Sscanf()
. The naming convention should be easy to follow along with.
Here is an example of Printf()
in action:
package main
import (
"fmt"
)
func main() {
const name, age = "Kim", 22
fmt.Printf("%s is %d years old.\n", name, age)
// It is conventional not to worry about any
// error returned by Printf.
}
The %s
formats a string, while the %d
formats an integer.
If, for whatever reason, you are uncomfortable with using format specifiers, Golang also offers a family of Print()
functions that take a list of strings as arguments and print them separated by whitespace.
math
This package gives you access to mathematical functions. All of them take and return float64 values and arguments.
Among the functions available are trigonometric functions for Sin, Cos, and Tan, exponential and logarithmic functions, a square root function, minimum and maximum functions, and “floor” and “ceil” functions that move the number to the nearest smallest and largest whole number, respectively.
os
The os
module exposes operating system functions. This includes opening and closing files using Open()
and Close()
, functions to spawn and kill processes, remove and create files, and exit the Golang program using Exit()
.
regex
This module provides functions to construct regular expressions and searching strings against them. This guide will not cover repulse expressions themselves; it's assumed you already know how to read them.
First, we must compile a regular expression string using Compile()
, and this will return a special Regexp object:
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`foo.?`)
fmt.Printf("%q\n", re.FindString("seafood fool"))
fmt.Printf("%q\n", re.FindString("meat"))
}
MustCompile()
is a version of Compile()
that panics and aborts the program if the regular| expression string is malformed.
After the regular expression is compiled, then we can search for any string with it using FindString()
. And if nothing matches the regular expression, it returns an empty string.
sort
The sort
module gives us functions to sort arrays with. Among other types of collections, it can sort string arrays, int arrays, float arrays, and even arrays with user-defined types.
package main
import (
"fmt"
"sort"
)
func main() {
s := []string{"Go", "Bravo", "Gopher", "Alpha", "Grin", "Delta"}
sort.Strings(s)
fmt.Println(s)
t := []int{5, 2, 6, 3, 1, 4} // unsorted
sort.Ints(t)
fmt.Println(t)
}
It also has functions for performing a binary search on arrays.
strings
This module contains a host of functions for splitting and joining strings, trimming characters from either side of the string, finding the index of characters in a string, manipulating the case of strings, and much more.
time
Finally, this module lets you get the current time as a time object using time.Now()
. You can add and subtract time objects from each other using the Add()
and Sub()
, and this technique allows you to measure elapsed time within programs. It can represent absolute times or questions of times using the same object. It also lets you get each time component, such as the year, month, day, hour, minute, and second, using separate function calls for each.
I haven't covered all the modules, but these are the ones you will find yourself using the most. Keep in mind that Golang has excellent documentation for all of these packages on their website so be sure to check that out too to discover more packages!
Top comments (0)