Table of Contents

GO

Go is a replacement of C, C++.

Go has some advantages when building simple, little services.
Simple language to build simle services.

So this language has API and syntax support for solving current prolems.
For microservices you need less polymorpism, but more concurency and verbosity.

  1. Build in concurrency. No mutex.
  2. Building for any platform
  3. Consistent API. Helpful when updating to new versions.
  4. One way to do things - less static code analysis needed

IDE: Gogland https://www.jetbrains.com/go/

There is a youtube channel about GO. HelloWorld, tooling,..
https://www.youtube.com/channel/UC_BzFbxG2za3bp5NRRRXJSw

Commands

Basic executable

package main

func main() {
	println("hello")
}

Build command

// in windows - builds a win application
go build -o mywin.exe

// or in ubuntu - builds a linux app
go build -o myfirstexecutable

Run command

Build and executes

$ go run main.go
hello

Docs of StandardLib

https://pkg.go.dev/std

GO packages

for imports

https://pkg.go.dev/

GO modules loading

Loading a module and tidy up dependencies

$ go get github.com/jboursiquot/go-proverbs
go mod tidy

GO private public functions

Capitized functions - are public.

small letter functions - are private.


//public
func Fprintln(w io.Writer, a ...any) (n int, err error) {
	p := newPrinter()
	p.doPrintln(a)
	n, err = w.Write(p.buf)
	p.free()
	return
}


// private
func newPrinter() *pp {
	p := ppFree.Get().(*pp)
	p.panicking = false
	p.erroring = false
	p.wrapErrs = false
	p.fmt.init(&p.buf)
	return p
}

Naked return

Naked return. The name of the variable to return is defined in the method signature as “greeting”


// greetWithNameAndAge returns a greeting with the name and age
func greetWithNameAndAge(name string, age int) (greeting string) {
	greeting = "Hello, my name is " + name + " and I am " + strconv.Itoa(age) + " years old."
	return
}

Return multiple values

Ya can retrurn multiple value

func vals() (int, int) {
	return 3, 7
}

func main() {
	a, b := vals()
	fmt.Println(a)
	fmt.Println(b)
}

Return multiple value - with errors

The first value is returned, when there is no error.

func divide(a, b int) (int, error) {
	if b == 0 {
		return 0, errors.New("cannot divide by zero")
	}
	return a / b, nil
}

Variables

The ':=' short variable assignment operator indicates that short variable declaration is being used. There is no need to use the var keyword or declare the variable type.


package main

import (
	"fmt"
	"github.com/jboursiquot/proverbs"
	"strconv"
)

// package variables
var x, y, z bool = true, true, true

// accesses the package level values
func packlvlvars() (bool, bool, bool) {
	return x, y, z
}

func main() {

	// method variables
	// below vars are covering the package-level values in the scope of current function


	// long variant
	// split declaration and assignment
	var mvar int
	mvar = 123
	fmt.Println(mvar)


	// combine declaration and assignment
	var mvar2 int = 123
	fmt.Println(mvar2)


	// declare multiple
	x, y, z := 1, 2, "bla"
	fmt.Println(strconv.Itoa(x) + strconv.Itoa(y) + z)

	// need a special value to get package variables
	a, b, c := packlvlvars()
	fmt.Println(strconv.FormatBool(a) + strconv.FormatBool(b) + strconv.FormatBool(c))

}


Pointers

// basic-types/pointers/end/main.go
package main

import (
	"fmt"
	"reflect"
)

func main() {
	// create a variable of type *T where T is an int
	var a *int

	// declare and assign `b` variable of type int
	valu := 100

	// assign the address of b to a
	pointr = &valu

	// print out the value of a which is the address of b
	fmt.Println(pointr)
	// returns: ptr
	fmt.Println("Type: %s", reflect.ValueOf(pointr).Kind() )

	// print out the value at the address of b
	fmt.Println(*pointr)
}

Structs & pass by reference or value

Structure to hold data in Go Lang

type author struct {
	first string
	last  string
}

// getter 
// attention - the assignment to struct - is derived from parenthesis after "func" keyword
// is declared OUTSIDE of struct :(
func (a author) fullName() string {
	return a.first + " " + a.last
}

// setter
// passing the reference, so that we change the exact object and not its value
// changeName changes the first and last name of the author
func (a *author) changeName(first, last string) {
	a.first = first
	a.last = last
}

func main() {
	// initialize author
	a := author{
		first: "Marcus",
		last:  "Aurelius",
	}

	// print the author's full name
	fmt.Println(a.fullName())
}

*address - passes by reference

Explains why to pass