# Go Basics
This section introduces basic types and string formatting. After that, you will dive into functions and methods in Golang.
# Numbers
Integer types are:
- int will be 32 or 64 bits long depending on the OS. However, one can specify precisely how many bits are used with 8, 16, 32, and 64.
- uint defines the unsigned integers, which are simply positive integers.
- uintptr is an integer "to hold the bit pattern of any pointer" (opens new window).
There are two aliases:
- byte for uint8
- rune for int32
The types for floating-point arithmetic are float32
and float64
. These are only an approximation for real numbers because of the finite precision (opens new window).
complex64
and complex128
represent complex numbers. These are useful in geospatial coordinate systems and scientific applications, among others. They have "real" and "imaginary" parts that are always floats
. When the real and imaginary parts are float32
, the complex number is a complex64
. Likewise, when the real and imaginary parts are float64
, the complex number is a complex128
.
# Strings
In Go, a string
is a read-only sequence of bytes. Therefore strings are immutable. They're encoded in UTF8 by default.
# Booleans
A bool
is a special 1-bit integer. It can represent true
or false
.
# Type declaration
In Go, the name comes before the type in the declaration. There are two ways to initialize a variable in Go.
First:
Second:
You can also use var to define variables without initialization:
This is equivalent to:
Without initialization, variables have so-called zero values which depend on their type.
To define constants, you must use the const
keyword instead of var
or :=
keywords.
Constants can be typed or untyped. For example, an untyped constant:
The untyped constant means that the type of hello
is not defined yet.
Because of static types in Go, you have more freedom with untyped constants than with typed ones. Compare the following two examples:
This first example works: the "number" constant is untyped, so the variable "f" can accept it (despite itself being typed float64
).
This second example does not work: the "number" constant and the variable "f" are differently typed (int
and float64
respectively).
# String formatting
fmt.Printf
writes to standard output and returns the number of bytes written and the write error. The string formatting is:
Here is an example code:
Compile this to see the output.
# Functions
Functions can take zero or more arguments and can return zero or more arguments. The syntax looks like the following:
If return variable names are given in the declaration, you do not need to explicitly return them.
For example, consider a swap function that switches the values of x
and y
:
You could also write:
Go also offers function closures:
Let's walk through func fibonacci()
in more detail:
- Go supports anonymous functions, which you return.
- You declare
x
andy
insidefibonacci()
, and use them inside the anonymous function.
x, y = y, x + y
works because the right side is evaluated fully before the left side.
Now write less idiomatic code to highlight some more aspects:
This will print the first 10 Fibonacci numbers.
Important here is that fibonacci()
returns a function, and this function is passed into loop()
as f
. On subsequent iterations, loop(n-1,f)
passes this anonymous function into itself recursively.
Here you used the control statement if
for the first time, to break out of the recursion. Each fibonacci()
, stored as f
in loop
, has its own x
and y
- this is called a closure. So, what happens if you split the loop into 2?
This will give the first 5 Fibonacci numbers twice.
To get the first 10, try the following:
Do you see why that works?
# Methods
Methods are defined on types. Go does not have classes. First, define a structure type:
You can use this structure for a variable declaration:
You also have access to members through the .
operator:
Now you can declare a method on it:
Methods are functions, but they have a so-called receiver argument (in the previous example r Rectangle
). You can use such a method with the .
operator:
Do you see how Area()
became a method of Rectangle
?
You can declare a method with a receiver only in the same package as the type is defined.
The following example is not declared on a struct
type:
Do you see how Abs()
became a method of the new type, MyNumber
?
# Pointer
A function argument is copied into the function. If you want to change the argument, you will require pointers. Pointers are addresses of variables. Look at an example:
The following function will not change i
:
Instead, try it this way:
The previous attempt will get the same result (0
) twice. Nothing happened to i
.
Now see what happens if you include a pointer:
Now you see that the value of i
changes. What happened is as follows:
&i
gives the address with type*int
, which is a pointer and expected by the functionfunc increase(i *int)
.*i
is the value the pointer points to.
You can also use pointers in methods to modify the receiver:
r.b
is the same as (*r).b
in this context, but it is easier to read.
Pointers are important.
This video provides a simple demonstration of functional programming in Golang, to clarify how functions interact to produce particular results.
To summarize, this section has explored:
- The basic types (including numbers, strings, booleans, and type declarations), string formatting, functions, and methods employed in Golang.
- Where to access online tests to practice implementing some simple coding examples for yourself.