Skip to content
John Mark edited this page Sep 9, 2025 · 51 revisions

Welcome to the GO-NOTES wiki!

Go

Function, Fields, Struct start in Capital letters are Public and Small letters are Private

type MyPublicStruct struct { //Accessible to other package (Public)
    ExportedField string // Accessible to other package (Public)
    privateField  int    // Accessible within package (Private)
}
type myPrivateStruct struct { // Accessible within package (Private)
    Data string // Accessible to other package (Public)
}
func testOnly(){} //Accessible within package (Private)
func Test(){} //Accessible to other package (Public)

defer

  • Execute code in the last line of main()
package main
import "fmt"

func main(){
  defer Last() //Execute code in last line of main()
  First()
}
func First() { fmt.Println("Print in first") }
func Last() { fmt.Println("Print in last") }

goto

  • Jump to the Labeled line.
package main
import "fmt"

func main(){
    var x int = 10
    y := 5
        if x > 5 { 
            fmt.Println("Value is greater: ", x)
            goto Test
        }   
        Test:
            if y < 9 { 
                fmt.Println("Value is less: ", y)
            }   
}

select

  • Wait for multiple channel operation
package main
import (
    "fmt"
    "time"
)
func main() {
    c1 := make(chan string)
    c2 := make(chan string)

    go func() {
        time.Sleep(1 * time.Second)
        c1 <- "one"
    }()
    go func() {
        time.Sleep(2 * time.Second)
        c2 <- "two"
    }()
    for range 2 {
        select {
        case msg1 := <-c1:
            fmt.Println("received", msg1)
        case msg2 := <-c2:
            fmt.Println("received", msg2)
        }
    }
}
Output:
received one
received two

Pointer

package main
import "fmt"

func main(){
    value := 42
    pointer := &value

    fmt.Printf("Value at address: %v\n", *pointer)

    *pointer = 100 

    fmt.Printf("New value:\t%v\n", value)
}

Module

Create a Go Module folder

$mkdir sample_module
$go mod init example.com/sample_module

Now the folder contain the go.mod (Go Module).

sample_module/
-- go.mod

Include other Module to current Module

$cd sample_module/
$go mod edit -replace example.com/other_module=../other_module
$go mod tidy

The code below will be added in the go.mod of sample_module.

//sample_module/go.mod
module example.com/sample_module
 
go 1.25.0
 
replace example.com/other_module => ../other_module

require example.com/other_module v0.0.0-00010101000000-000000000000

We can now use the codes and packages from other_module by importing the other_module in go file.

//sample_module/sample_package/sample.go
package sample
import(
  //Importing the other_module folder
  "example.com/other_module"
  //We can also include the package folder from other_module
  "example.com/other_module/other_package"
)
func main(){}

Package

Go file that use "package main" in a Go Module can share code

//hello.go
package main
func main(){
   Test() //Test func called here
}
//test.go
package main
func Test(){}

Go Workspace

We use Go Workspace to include multiple Module

$cd test_project
$go work init ./hello_module

To add more Module use the command below.

$go work use ./greeting_module

The command above will generate the go.work file

go 1.25.0
use (
    ./hello_module
    ./greetings_module
)

We can now include the module in our project

//test_project/hello_module/module1/module1.go
package main

import (
    "fmt"
    "example.com/greetings_module/module2"
)
func Module1(){
    fmt.Println("Module 1")
}
func main(){
    module2.Module2()
    Module1()
}
//test_project/greetings_module/module2/module2.go
package module2

import (
    "fmt"
)
func Module2(){
    fmt.Println("Module2")
}

To run the module

$go run ./hello_module/module1/ 
$go build ./hello_module/module1/
$./module1

Variables

Data Types

bool
string
int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr
byte // alias for uint8
rune // alias for int32
     // represents a Unicode code point
float32 float64
complex64 complex128

Variables without initial value are given with default value

0 - for numeric types
false - for the boolean type
"" - (the empty string) for strings

Variable assignment

package main
import "fmt"

const (
    g = 8
    h = 3.9
)
var (
    e = "Testing"
    f = "Another one"
)
func main() {
  var a, b = 6, "Sample"
  c, d := 7, "Only"       //:= Short variable declaration operator 
  fmt.Println(a) //6
  fmt.Println(b) //Sample
  fmt.Println(c) //7
  fmt.Println(d) //Only
  fmt.Println(e) //Testing
  fmt.Println(f) //Another one
  fmt.Println(g) // 8
  fmt.Println(h) // 3.9
}

Short Variable Declaration

func main() { 
   //var name string
   //name = FullName("john", "doe") 
   
   //This is same to "short variable declaration" :=
   name := FullName("john", "doe")  
   fmt.Println(name)
}
func FullName(fname string, lname string) (name string) {
   name = fname + lname
   return name
}

Loops

for, range, break, continue

package main
import (
    "fmt"
)
func main(){
    names := []string{"John Cena", "Katy Perry", "William Roberts", "Jullian"}
    for i:=0; i < len(names); i++ {
        if names[i] == "Katy Perry" {
            continue //Use to Skip one or more iteration of the Loop. "Katy Perry" will no be printed)
        }   
        if names[i] == "William Roberts" {
            break   //Use to Break/Terminate the Loop 
        }   
        fmt.Println(names[i])
    }   
    numbers := []int{56 ,78, 90} 
    for index, val := range numbers {
        fmt.Printf("%v\t%v\n", index, val)
    }   
    //Output:
    /* John Cena
    0   56
    1   78
    2   90 */
    for { //Infinite Loop
       fmt.Println("Infinite Loop")
    }
    
}

Functions

Function start with Capital letter are public (access in other package) while Small letter are private (within package).

//module/package_one/package1.go
package package1
func Test(){}
//module/package_two/package2.go
package package2
import(
   "module/package_one"
)
func testAgain(){}
func main(){
   package1.Test()
   testAgain()
}

Multiple return

func Test(name string)(string, int) {
   return "john", 45 //return string and int
}

Naked and Named return

func FullName(fname string, lname string) (name string, namejr string) {
   name = fname + lname
   namejr = fname + lname + " jr."
   return    //This is Naked return
   //We can also do "return name" this is Named return
}
func main() { 
   FullName("john", "doe") 
}

Variadic function

package main
import "fmt"
func sum(nums ...int){
    fmt.Print(nums, " ")
    total := 0
    for _, num := range nums {
        total += num 
    }   
    fmt.Println(total)
}
func main(){
    sum(1, 2, 3)
    numbers := []int{2, 4, 5, 8}
    sum(numbers...)
}
//Output:
[1 2 3] 6
[2 4 5 8] 19

Closure

package main
import "fmt"

func intSequence() func() int { //expect a return function with int
    i := 0
    return func() int { //return a function
        i++ 
        return i
    }   
}
func main(){
    nextInt := intSequence()

    fmt.Println(nextInt())
    fmt.Println(nextInt())
}

Recursion

package main
import "fmt"

func main(){
    fmt.Println(plus(4)) //Output: 5
}
func plus(num int) (result int) {
    if num > 3 { //Check if higher than 3
        result = num  + plus(num - 3) //Re-check this if higher than 3 if not go else return 1
    } else {
        result = 1 
    }   
    return
}

Anonymous

//Function without name
func () {
  fmt.Println("Anonymous func")
}()
//Assigned to a variable
add := func(x int) int {
    return x + 2
}
fmt.Println(add(5)) //7

Function as parameter

package main
import "fmt"

 func Operate(a, b int, AnotherOperation func(int, int) int) int {
      return AnotherOperation(a, b)
 }
func main(){
    add := func(x, y int) int { return x + y } 
    result := Operate(3, 4, add)
    fmt.Println(result) //Output: 7
}

Methods (Function with Receiver) are functions bound to a type ()

package main

import (
	"fmt"
	"math"
)
type TestStruct struct {
	X, Y float64
}
//Receiver
func (p TestStruct) TestResult(add int) float64 {
	return math.Sqrt(p.X * p.X + p.Y * p.Y) + float64(add) //converting to float64
}
func main() {
	v := TestStruct{3, 4}
	fmt.Println(v.TestResult(4)) //Output: 9
}

Function main and init

package main
import "fmt"

func main(){
   fmt.Println("Main executed after init")
}
func init(){
   fmt.Println("Init executed before main")
}
//Output:
Init executed before main
Main executed after init

Conditional

Channels (For Asynchronous)

package main
import (
        "fmt"
        "time"
)
func main(){
        c1 := make(chan string)
        c2 := make(chan string)

        go func(){
                time.Sleep(1 * time.Second)
                c1 <- "one"
        }()
        go func(){
                time.Sleep(2 * time.Second)
                c2 <- "two"
        }()

        for range 2 {
                select {
                        case msg1 := <- c1:
                                fmt.Println("received", msg1)
                        case msg2 := <- c2:
                                fmt.Println("received", msg2)
                }
        }
}
Output:
recieved one
received two

Struct

package main
import "fmt"

type person struct {
    name string
    age int 
}
func newPerson(name string) *person {
    p := person {name: name}
    p.age = 42
    return &p
}
func main(){
    fmt.Println(person{"Bob", 34})
    fmt.Println(person{name: "Thamuz"})
    fmt.Println(newPerson("Hilda"))

    s := person{name:"leomord", age: 40} 
    fmt.Println(s.name)

    sp := &s  
    fmt.Println(sp.age)
}
Output:
{Bob 34}
{Thamuz 0}
&{Hilda 42}
leomord
40

Interface

package main

import (
    "fmt"
    "math"
)

type operation interface {
    addition() float64
    subtraction() float64
}
type dataType1 struct {
    num1, num2 float64
}
type dataType2 struct {
    num3 float64
}
//======= Required to implement the struct to the two function in interface
func (p dataType1) addition() float64 {
    return p.num1 + p.num2
}
func (p dataType1) subtraction() float64 {
    return math.Pi * p.num1 - p.num2
}
//===== Required to implement the struct to the two function in interface
func (s dataType2) subtraction() float64 {
    return math.Pi - s.num3
}
func (s dataType2) addition() float64 {
    return s.num3 - 20
}
//=====
func process(o operation){
    fmt.Println(o)
    fmt.Println(o.addition())
    fmt.Println(o.subtraction())
}
func main(){
    p := dataType1{num1: 4, num2: 6}
    s := dataType2{num3: 45.2}
    process(p)
    process(s)
}

Enums

package main

import "fmt"

type Status int

const (
    StatusActive Status = iota //iota automatically assign a number from 0 - 1 
    StatusPending
    StatusInactive
)

func (s Status) String() string { //Method type receiver 
    switch s {
        case StatusActive:
            return "Active"
        case StatusPending:
            return "Pending"
        case StatusInactive:
            return "Inactive"
        default:
            return "Unknown"
    }
}
func main(){
    taskStatus := StatusPending
    fmt.Printf("Task Status: %v\n", taskStatus) //Output:Task Status: Pending
    if taskStatus == StatusInactive {
        fmt.Println("Task is inactive")
    } else {
        fmt.Println("Task is active")
    }
}

Error Handling

package main

import (
    "fmt"
    "errors"
)

func testError(arg int) (int, error) {
    if arg == 42 {
        return -1, errors.New("Cant work with 42")
    }   
    return arg + 3, nil 
}

func main(){
    for _, i := range []int{47, 42} {
        if val, err := testError(i); err != nil {
            fmt.Println("failed:", err)
        } else {
            fmt.Println("worked:", val)
        }   
    }   
}

Output Verbs

Verbs

Resources

Go By Example

Go Tutorial

Youtube: Go Tutorial Edge