Note 1: The code in this repository is based on Go 1.11.*. It should work on other versions as well.
Note 2: The file names do not follow the Go language convention, it's there only to show you the flow of this tutorial.
- 1. Installation
- 2. Setup
- 3. Getting Stated and Conventions
- 4. Let's Start Coding
- 5. What's Next
Installation is straightforward, just download the executable file and follow the instruction.
For windows, you will have to download the MSI executable file. Remember that MSI is a 64-bit so make sure you have a 64-bit processor.
Goto https://golang.org/dl/ and download the latest version, for example for Go 1.10.1 it is go1.10.1.windows-amd64.msi
. Once installed, you check it by opening your command prompt and type in go version
.
A pre-built package is available to download and install. Just follow the installation window. Download the latest version at https://golang.org/dl/, for example, for Go 1.10.1 the file name is go1.10.1.darwin-amd64.pkg
For Linux distribution, there is no pre-built package, but it is easy to install. Just download the latest *.tar.gz file from https://golang.org/dl/, for example, for Go 1.10.1 the file is go1.10.1.linux-amd64.tar.gz
.
Once downloaded, follow the steps:
- Open your terminal and change the directory to where you download the tar.gz file, then type in:
tar -c /usr/local -xzf go1.10.1.linux-amd64.tar.gz
- Then add the
/usr/local/go/bin
to the path by doing:
export PATH=$PATH:/usr/local/go/bin
You can test it by typing in go version
.
Note: You can also add file to your home file by just replacing the
/usr/local/
with/home/username
,username
being your user folder.
Windows and macOS should automatically update the path to Go, if not you will have to add the path - installed-folder/go/bin
, where installed-path is where you have installed the Go language. For Linux, see above.
I am using JetBrains GoLand IDE but you can use any IDE you wish, I would recommend using VSCode.
Go website has a wonderful way to test your code without installing Go libraries on your system, its called The Go Playground.
Go also provides a way to run playground (you will need internet though) on your system. Type in:
> godoc -http=:6060 -play -index
Now open your browser and type in localhost:6060
, this should open playground.
There are few limitations when using the Go playground as its being run on a secured server that has no access to external world:
- You cannot run HTTP requests or host your web server.
- The playground fakes the files system so that your IO works correctly.
- The date and time are always constant - November 10, 2009, at 11:00 p.m.
- You can work with only one source code at a time; you cannot have multiple go file and import them locally unlike you do on your system.
- Moreover, it is free.
Before we dive into the coding part of Go language, let's look into some coding and naming conventions of this programming language.
According to the Go docs, there is no right or wrong way to name your file - you can either use underscores or camelCase or Pascal Case or small letters, but most Go developers use underscore to name their files. The underscore contradicts the standard library files, for example:
go/src/mime/encodedword.go
go/src/mime/encodedword_test.go
encodedword.go
is the name of the main file where other methods are available, and their tests can be found in encodedword_test.go
. Simple as.
Sometimes you wish to run the file on Windows, Linux or both. In that case, you can name your files something like this
filename.go - compiles universally
filename_windows.go - compiles on windows only
filename_unix.go - compiles on posix.
filename_amd64.go - compiles on 64-bit processors only
filename_arm.go - compiles on arm processors only
Go build takes care of what to use depending on your operating system, for more information see https://golang.org/pkg/go/build/
A function always starts with the keyword func
, the name given to it are of two types; one that begins with a capital letter and the other that begins with a small letter.
For example:
package main
import (
"strconv"
"fmt"
"reflect"
)
func main() {
sum := Add(1, 2)
fmt.Println(sum)
fmt.Println(reflect.TypeOf(sum))
}
func Add(a int, b int) string {
return toString(a + b)
}
func toString(c int) string {
return strconv.Itoa(c)
}
Let's consider the above example, the Add()
function takes in two numbers, adds it and converts it to a string by using toString()
function. The Add()
function is available throughout the application, as in it can be imported to other go files. Whereas the toString()
can only be used locally.
Under c:\go\bin
there are three commands:
This is the primary command you will be using throughout the tutorial. It incorporates more than a dozen commands in it. We will look into most of them in this tutorial. If you type in go
you will see all the available commands and its description.
godoc
is similar to javadoc
but for Go packages. If you enter godoc fmt
, it will display all the documentation related to fmt
package. Typing godoc
itself will print out all the command flags it can take.
This command can be used to format your source code. You can use this by typing gofmt filename.go
this will only print out the formatted text from the file but does not write it, to make it write the file you should add -w
flag - gofmt -w filename.go
.
Go follows some strict norms on how you create your workspace structure. The root directory can be any name but should not contain any space or special characters.
The structure should look something like this:
workspacename
|
+- src
+- bin
`- pkg
src
is for your source files, bin
for executables and pkg
for external libraries.
Once, the folder has been set; the next thing is to create a GOPATH
to do so type in:
set GOTPATH=%USERPROFILE%\gowork
Note: I would create this directory in my
home
folder. It is up to you where to create it.
You can check all the Go environments by typing in go env
. When you change directory to the src
folder with a go file in it and type in go install
it creates an executable file in the bin
folder.
Note: Ignore
_#
(where#
is the number) as the filename below, the number represents the flow of things to start and end with.
Code Structure
src
|
`- helloworld_1.go
Some helpful Go CLI commands:
godoc
- Used to get the documentation for a given package. Examplegodoc fmt
.gofmt
- To format a Go file to its specifications. Examplegofmt -w filename.go
-w
will write the file.go
- It has a lot of sub-commands, in this notes we will be using mostlygo run
go run
- Builds and runs a Go file. Examplego run filename.go
go build
- Build an executable file. Examplego build filename.go
Say we have a file called helloworld_1.go
, which has the following content.
package main // The main method should always be in "main" package
import "fmt" // Standard Go library for formatted I/O
func main() { // Go always starts at "main" method
fmt.Println("hello world") // outputs to I/O with new line.
}
To run the file you should use - go build filename.go
this compiles the file to filename.exe
(in windows). In this case it will look something like this:
Or you can also use go run
to build the file in temp
folder and run it. Something like:
This section looks into pkg package.
A function in Go can return n
number of objects, which includes errors
.
For example fmt.Println
can have multiple returns:
stringLength, err := fmt.Println(str1, str2)
If there is no error, the content in the stringLength
will be returned and the err
will be equal to nil
.
For user input you can use fmt.Scanln(&ref)
and reference to a string variable, but the problem with the Scanln
is that whenever it encounters a space, the word after the space is given to a new variable.
for example:
var s string
var s2 string
// Send in the reference of the string s
fmt.Scanln(&s, &s2) // hello hi
// Print the value of it.
fmt.Println(s, s2) // hello hi
To take the input from the user as is, you will have to use different packages, such as bufio
and os
.
In this section we will look into formatting string, date time, date types.
Using var
keyword and an assignment operator with a data type you can declare a value.
var anInteger int = 30
var aString string = "Hello!"
Go allows you to implicitly declare a variable without using a data type and the var
keyword and replace them by using :=
.
anInteger := 30
aString := "Hello!"
Above code is still static and cannot be changed.
Explicit:
const anInteger int = 30
const aString string = "Hello!"
Implicit:
const anInteger = 30
const aString = "Hello!"
All data types are spelled in lower case.
bool
- Booleans valuesstring
- String type- Integers:
- Fixed Integers:
uint8 uint16 uint32 uint64
int8 int16 int32 int64
- Aliases: They could be a 32 bit or a 64 bit depending upon the operating system.
byte uint int uintptr
- Floating values:
float32 float64
- Complex numbers:
complex64 complex128
- Data collections:
Arrays Slices Maps Structs
- Language organization:
Functions Interfaces Channels
- Data Management:
Pointers
Source - workingwithstrings_4.go
Go language is case sensitive as in hello != Hello
. For more information on strings
see http://golang.com/pkg/strings/
Math Operation
Operator | Definition |
---|---|
+ | Add |
- | Subtract |
* | Multiply |
/ | Divide |
% | Remainder |
Bitwise Operation
Operator | Definition |
---|---|
& | Bitwise AND |
| | Bitwise OR |
^ | Bitwise XOR |
&^ | Bitclear |
>> | Right Shift |
<< | Left Shift |
In Go, numeric types don't implicitly convert, i.e you cannot add a float to int, the only way you can add ghem is by converting an int to float. For example:
int1 := 30
float1 :=30.1
fmt.Println(float64(int1) + float1)
For more complex math problems see http://golang.com/pkg/math/.
When trying to format date and time make sure you format based on the constant numbers given in the package.
1 - Month
2 - Day
3 - Hour
4 - Minutes
5 - Seconds
6 - Year
7 - Timezone
For example:
shortFormat := "2/1/06"
fmt.Println("Today is", time.Now().Format(shortFormat))
In this section we will look into some complex types such as pointers and collections such as arrays, maps and Structs.
Like C/C++, Go also support pointers natively.
All the contents in an array are of same type. Like Java, the first index always starts with 0
.
There are some memory implication when using arrays in Go, unlike C/C++ (where arrays are pointers) arrays in Go are values i.e. when assigning one array to another copies all the contents of it. Passing an array to the function will pass a copy of the array and not the pointer.
A slice is an abstraction layer that sits on top of an Array. Like arrays all the contents in the slices are of the same type, but unlike it, slices can are resizeable and can be sorted easily.
Go's runtime is statistically linked into each compiled application. Go's memory is managed my the runtime on a different thread, that means memory allocation and deallocation is completely done automatically in the background.
To understand how the memory allocation works there two function that you'll need to understand - make()
and new()
, these function can be used to initialise maps
, slices
and channels
.
In most cases you will like be using make()
instead of new()
.
- Allocates but does not initialise memory
- Results in zeroed storage but returns a memory address
- Allocates and initialise memory
- Results in non-zeroed storage but returns a memory address
You must always initialise complex objects before adding values, declaring them without make()
will cause a panic.
For example:
var m map[string]int // key value pair of string and integer.
m["key"] = 10
fmt.Println(m)
With the above code you will get a panic error at the second line as you cannot add a value to zeroed memory. To fix this you can do;
m := make(map[string]int) // key value pair of string and integer.
m["key"] = 10
fmt.Println(m)
// map[key:42]
Memory is deallocated by using garbage collector (GC), only the objects that are out of scope or set to nil
are eligible.
For more information on GC you can go to https://golang.org/pkg/runtime/.
Maps are unordered collections of key-value pairs aka hash table.
Structs in Go have similar function to C's struct and Java's classes. They both contain data and methods, but unlike Java, Go doesn't have an inheritance model.
In this section we will look into how to use struct to store data.
In this section we will look at how the conditions in Go differs from C.
You will have to remember that the else
keyword should come after the braces. Example:
// This is wrong. you will get an error
if ...{
...
}
else {
...
}
// Instead use this
if ... {
...
} else {
...
}
This is because the way the Go lexer see the line feeds.
Go's switch statement improvises C's and Java's. Like the recent versions of Java, Go can evaluate simple types, not just constants and strings. The code flow jumps from one case to another once the case if found, this means you don't have to add the redundant break
statement.
Unlike Java there is no while
statement in Go, but there are extended version of the for
loop, which will be seen in this section.
Go is organised as packages, each of these packages has functions. Any function starting with a small letter is private to that package but if it's starting with a capital letter it's public and be used outside the package.
Unlike Java, Go has no function overloading in Go that means you'll need to create a different function for each output you want.
Source - multiple_return_values_16.go
Functions in Go can return multiple values, its the second is usually an error vale (we will talk about this in handling errors).
For this thing to work, you will have to setup a workspace as mentioned at the starting of the tutorial. Once you have this, create a file as <GOPATH>/src/libraries/library.go
and copy the main
from multiple_return_values_16.go to it. After this is done, next create another file under <GOPATH>/src/stringutil/stringutil.go
, copy FullName
and FullNameNakedReturn
to it or create any public functions.
Open your terminal, change your directory to <GOPATH>/src/libraries/library.go
and type in go install
, this will create a executable file under <GOPATH>/bin/libraries.exe
.
Unlike Java or C++ where a method is a member of a class
, in Go, a method is a member of type
.
Unlike Java, Go does not have an extends
keyword, rather an method that has the same type and name is an interface.
Unlike other programming languages, Go does not provide classic exception handling like try...catch..
block.
Deferred statements are executed last in first out order.
Source - walkingDirectory_24.go
In the next tutorial (coming soon) we will look into using Go to develop a RESTful web application.