Golang Cheatsheet

Installing #

After you download go from the official website, you need to move the go directory under /usr/local/ directory.

Then, open the .bashrc or .bash_profile system configuration file and paste the following:

export GOROOT=/usr/local/go
export GOPATH=$HOME/the_name_of_your_workspace_directory
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin

Basic Go Commands #

go version
// important env variables that Go uses
go env
// formatting a go file
go fmt
// executing a go file
go run 
// building executable of our go program
go build 

Printing #

Printing format: https://pkg.go.dev/fmt#hdr-Printing

Strings #

	fmt.Println("A string")

	fmt.Println(`
	This is 
	a multi-line \n
	String `)

	fmt.Println("\n Hi")

	fmt.Println("😀")

        // Output
        A string

	This is 
	a multi-line \n
	String 

        Hi
        😀

Comparison Operators #

1 < 2 //true
1 > 2 //false
1 == 2 //false
1 != 2 //true

Variables #

	var myInt int = 2
	fmt.Println(myInt)

        // Auto assignment 
	var myInt, myString = 2, "String"
	fmt.Println(reflect.ValueOf(myInt).Kind(), reflect.ValueOf(myString).Kind())
        //Output
        // int string

        // Variable shorthand syntax
        myInt := 2
        
        // multi line variable declaration
        var (
            var1 = 1
            var2 = 2
        )

Exported Variables #

These variable start with a capitalised variable name, and we can access the value of these variables even if they are declared on a different scope or package.

var ExportedVariable = 5
func main() {
     fmt.Println(anotherpackage.ExportedVariable)
}

Type Declaration #

type customInteger int
var integer customInteger

Arrays & Slices #

	// Declairing an array
	var array1 [3]string
	array1[0] = "One"
	fmt.Println(array1[0])

	// Using slices
	array2 := []string{}
	array2 = append(array2, "Anastasis")
	array2 = append(array2, "Kentominas")
	fmt.Println(array2)

Maps #

Maps have unique key-value pairs.

    // Initialising & assigning a map
    personal := map[string]string{
      "Name": "Anastasis",
      "Birthday": "1995",
    }
    // Delete a key from a map
    delete(personal, "Name")


    info := map[string]int{}
    info["No1"] = 1
    info["No2"] = 2

Conditionales #

	age := 27

	if age < 18 {
		fmt.Println("You are underage")
	} else if age > 18 {
		fmt.Println("You are an adult")
	} else {
		fmt.Println("RIP")
	}

// Using a switch statement
	age := 27

	switch {
	case age == 27:
		fmt.Println("You are right")
	case age < 18:
		fmt.Println("You are underage")
	case age > 18:
		fmt.Println("You are an adult")
	}

// Or
	age := 27

	switch age {
	case 1, 2, 3, 5, 7, 8:
		fmt.Println("Nope")
	case 9, 14, 25, 27:
		fmt.Println("Yeap")
	default:
		fmt.Println("Non of case confitions match")
	}

Loops #

For-each range loops #

	strings := []string{"one", "two"}
	for i, s := range strings {
		fmt.Println(i, s)
	}

3 component loop #

	var sum int
	for i := 0; i < 10; i++ {
		sum += i
	}
	fmt.Println(sum)

Break & Continue #

        var sum int
	for i := 0; i < 10; i++ {
		if sum == 3 {
			fmt.Println("3 found, continuing")
			sum += 1
			continue
		}
		if sum == 34 {
			fmt.Println("34 found, exit for loop")
			break
		}
		sum += i
	}
	fmt.Println("Sum is: ", sum)

Functions #

func main() {
	result := printPerson("Anastasis", 27, "engineer")
	fmt.Println(result)
}

func printPerson(name string, age int, jobTitle string) string {
	return fmt.Sprintf("%s is %d year old and he is a %s", name, age, jobTitle)
}

It is important to mention that we can give the return type along with a variable name, and then, we can assign the return value to that variable which will be automatically returned by only using the keyword return in our function:

func printPerson(name string, age int, jobTitle string) (returnValue string) {
	returnValue = fmt.Sprintf("%s is %d year old and he is a %s", name, age, jobTitle)
	return
}

A function can return multiple types, and we can unpack each return type on function call:

func main() {
	addResult, isTotal := add(1, 2)
	fmt.Println(addResult, isTotal)
}

func add(a int, b int) (int, bool) {
	return (a + b), false
}

Function recursion in GO

func main() {
	fmt.Println(recursion(11))
}

func recursion(i int) int {
	if i < 2 {
		return i
	}
	return recursion(i-1) + recursion(i-2)
}

Init() #

The init function is invoked by Go implicitly, before the main function.

func main() {
	fmt.Println("Env variabled have been exported, begin program...")
}

func init() {
	fmt.Println("Checking environment variables....")
}
Checking environment variables....
Env variabled have been exported, begin program...

It is worth mentioning that we can have multiple init() function in the same go file, and they are going to be invoked from top to bottom order.

Another interesting point is that if we invoke a function from a different package, in our main package, init() function from the different package will be invoked first, before that init() function in the main package.


Packages #

We can bundle all the functions that deal with the same task.

Here, we create a new folder named package1 inside the myfirstgo module.

package package1

func MyFirst() string {
	return "Hello"
}

and then, in main.go

package main

import (
	"fmt"
	"myfirstgo/package1"
)

func main() {
	fmt.Println("hi")
	fmt.Println(package1.MyFirst())
}

User Input #

	reader := bufio.NewReader(os.Stdin)
	fmt.Println("You name:")
	phrase, _ := reader.ReadString('\n')
	fmt.Println(phrase)

Files Interaction #

Write to new file #

	message := "hello man"
	out := ioutil.WriteFile("/path/myfirstgo/haha.txt", []byte(message), 0644)

	if out != nil {
		fmt.Println("Unable to write to file")
	} else {
		fmt.Println("Done")
	}

Pointers #

	x := 5
	y := x
	fmt.Println("Original x: ", x)
	fmt.Println("y := x: ", y)
	
	y = 7
	fmt.Println("After change y = 7, y value: ", y)
	fmt.Println("After change y = 7, x value: ", x)

//Output:
Original x:  5
y := x:  5
After change y = 7, y value:  7
After change y = 7, x value:  5

In the example above, we created a new variable y and we assigned the value of the x reference to it.
We didn’t change the value of x, when changing the value of y because y is not pointing to the same memory address as x.

We can do this by referencing y to the same memory address that x exists. Now that we have y referencing to the same memory address with x, we can dereference y (access to the value the pointer y points to) and change the value of it.
This way x and y are pointing to the same memory address now which has the same value assigned to it.

&x returns a *int (pointer to an int)

	x := 5
	y := &x
	fmt.Println("Original x: ", x)
	fmt.Println("y := &x, y value: ", y)

	*y = 7
	fmt.Println("After change *y = 7, y value: ", y)
	fmt.Println("After change *y = 7, x value: ", x)

Output:
Original x:  5
y := x:  0xc0000b2008
After change y = 7, y value:  0xc0000b2008
After change y = 7, x value:  7

Flags #

	var name string
	var print bool

	flag.StringVar(&name, "name", "DefaultName", "Name of engineer")
	flag.BoolVar(&print, "print", false, "Print to console")

	flag.Parse()

	if print != false {
		fmt.Println("You name is ", name)
		os.Exit(0)
	}

and the usage would be:

go run main.go -print

Powered by BetterDocs

Leave a Reply