Golang Quickstart For Developers

main package

package main

import "fmt" //format

func main() {
	fmt.Println("Hello, 世界")
}

function

func add(x int, y int) int {
	return x + y
}

func swap(x, y string) (string, string) {
	return y, x
}

a, b := swap("hello", "world")

variable

var i, j int = 1, 2
var c, python, java = true, false, "no!"
k := 3
var i int // == 0

conversion

var f float64 = float64(i)

build go file

go build main.go
./main

GOOS=darwin GOARCH=amd64 go build main.go

create new module

go mod init example

install program (build + move binary)

go install example/user/hello

testing

package morestrings

import "testing"

func TestReverseRunes(t *testing.T) {
    cases := []struct {
        in, want string
    }{
        {"Hello, world", "dlrow ,olleH"},
        {"Hello, 世界", "界世 ,olleH"},
        {"", ""},
    }
    for _, c := range cases {
        got := ReverseRunes(c.in)
        if got != c.want {
            t.Errorf("ReverseRunes(%q) == %q, want %q", c.in, got, c.want)
        }
    }
}

// terminal: go test

for loop

for i := 0; i < 10; i++ {
	sum += i
}

conditions

if x < 0 {} else if {} else {}

switch os := runtime.GOOS; os {
	case "darwin":
		fmt.Println("macOS.")
	default:
		fmt.Printf("%s.\n", os)
}

defer

func main() {
	defer fmt.Println("world") //LIFO

	fmt.Println("hello")
}

pointer

var p *int
p = &i
fmt.Println(*p)

struct

type Vertex struct {
	X int
	Y int
}

Vertex{1, 2}
Vertex{X: 1}

v.X = 4

array

var a [10]int
primes := [6]int{2, 3, 5, 7, 11, 13}

var s []int = primes[1:4] // slice

len(s)
cap(s)

b := make([]int, 0, 5) // len(b)=0, cap(b)=5

s = append(s, 0)

for i, v := range pow {}

map

type Vertex struct {
	Lat, Long float64
}

var m map[string]Vertex

func main() {
	m = make(map[string]Vertex)
	m["Bell Labs"] = Vertex{
		40.68433, -74.39967,
	}
	fmt.Println(m["Bell Labs"])
}

var m = map[string]Vertex{
	"Bell Labs": Vertex{
		40.68433, -74.39967,
	},
	"Google": Vertex{
		37.42202, -122.08408,
	},
}

m[key] = elem
elem = m[key]
delete(m, key)
elem, ok = m[key]

closure

func adder() func(int) int {
	sum := 0
	return func(x int) int {
		sum += x
		return sum
	}
}

method (function with receiver)

func (v Vertex) Abs() float64 {  // call by value
	return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func (v *Vertex) Scale(f float64) {} // call by reference

interface

type Abser interface {
	Abs() float64
}

type MyFloat float64

func (f MyFloat) Abs() float64 {
	if f < 0 {
		return float64(-f)
	}
	return float64(f)
}

interface type assertion

t, ok := i.(T)

errors

i, err := strconv.Atoi("42")
if err != nil {
    fmt.Printf("couldn't convert number: %v\n", err)
    return
}

type MyError struct {
	When time.Time
	What string
}

func (e *MyError) Error() string {
	return fmt.Sprintf("at %v, %s",
		e.When, e.What)
}

func run() error {
	return &MyError{
		time.Now(),
		"it didn't work",
	}
}

func main() {
	if err := run(); err != nil {
		fmt.Println(err)
	}
}

type parameter

func Index[T comparable](s []T, x T) int

generic type

type List[T any] struct {
	next *List[T]
	val  T
}

goroutine

go f(x, y, z)

channel

ch := make(chan int)
ch <- v // send
v := <-ch // receive

c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
x, y := <-c, <-c


close(c)

select

func fibonacci(c, quit chan int) {
	x, y := 0, 1
	for {
		select {
		case c <- x:
			x, y = y, x+y
		case <-quit:
			fmt.Println("quit")
			return
		}
	}
}

mutex

package main

import (
	"fmt"
	"sync"
	"time"
)

type SafeCounter struct {
	mu sync.Mutex
	v  map[string]int
}

func (c *SafeCounter) Inc(key string) {
	c.mu.Lock()

	c.v[key]++

	c.mu.Unlock()
}


func (c *SafeCounter) Value(key string) int {
	c.mu.Lock()

	defer c.mu.Unlock()

	return c.v[key]
}

func main() {
	c := SafeCounter{v: make(map[string]int)}

	for i := 0; i < 1000; i++ {
		go c.Inc("somekey")
	}

	time.Sleep(time.Second)
	fmt.Println(c.Value("somekey"))
}