Head first Go (summary) - a1k89/Blog GitHub Wiki

17.07.2021

Chapter 1. let’s get going: Syntax Basics

  • Static types
  • You may use := to assign value and type for variable at once (in once action)
  • Commands:
go run hello.go - simple run (testing)
go fmt hello.go - format file (is like as linter)
go build hello.go - make build (executable file)
go version - check version

Chapter 2. which code runs next?: Conditionals and Loops

  • If/else - is like as python if/else
  • Methods can return error. Please catch it in err variable
for someVar := 1; someVar < 100; someVar ++ {
   fmt.PrintLn("some var: ", someVar)
}

Chapter 3. call me: Functions

  • go is a pass-by-value
  • Pointers - use & to catch original (not copy)
  • To declare pointer: &int, to pass - *someValue

Chapter 4. bundles of code: Packages

  • <user>/go/bin|package|src
  • In src your modules
  • You may to create packages: <packagename>/packagename.go
  • For import - use first letter of function or constant as a big!
  • go install - save bin (executable) file of package in bin directory
  • godoc -http=:8000 - documentation

Chapter 5. on the list: Arrays

  • Declare arrays:
var someArr [3]int
or
someArr := [3]int
or
someArr := [3]int {1,2,3}
  • Loop as:
for index, value := range someArr {
    ... some logic here
}
  • Read from file:
file, err := os.Open("filename")
if err != nil {
    log.Fatal(err)
}
scanner := bufio.NewScanner(file)

// Read each line of file:
for scanner.Scan() {
    line := scanner.Text()
    ...make some work..
}

Chapter 6. appending issue: Slices

  • Slice is a top of array
  • Declare:
var mySlice []string
mySlice = append(mySlice, "hello")
mySlice = append(mySlice, "bay")

19.07.2021

Chapter 7. labeling data: Maps

  • Map is like as Dict in python
  • To create map:
var myMap map[string]int // declare here
myMap = make(map[string]int) // Create empty map
or
myMap := map[string]int{} // Declare and create empty map
  • In python we can get value of dict via get('some_key'). In go:
myMap := map[string]int{"one":1, "two":2}
value, ok := myMap["one"] // ok is true
value2, ok := myMap["hello"] // ok is false 

Chapter 8. building storage: Structs

  • Is like as class in python
  • Create structure:
type Address struct {
    Country string
    City string
    Street string
}

type People struct {
    Name string
    Address
}

....in some code

people := People{name: "Alex", "Country": "RU", "City":"MSK", "Street":"Noname"}

Chapter 9. you’re my type: Defined Types

  • You may create you own type
  • Is like as from swift (typealias..)
  • To create you own type:
type MyOwnString string

myStr := MyOwnString("Hello)
....
  • In Go you may to create like swift extensions - pass type as reciever:
type MyOwnString string

func (m MyOwnString) SayHello() {
    fmt.Println("say hello from", m)
}
  • With pointers (not by value):
type MyOwnString string

func (m *MyOwnString) SayHello() {
    m = "Buy world!"
    fmt.Println("say hello from", m)
}

func main() {
    myVar := MyOwnString("hello world") // if print - return hello world
    myVar.SayHello()
    fmt.Print(myVar) // Return Buy world!
}

20.07.2021

Chapter 10. keep it to yourself: Encapsulation and Embedding

  • In Go we can embed one structure to another as anonymous
  • All fields from child structure will be available in parent (embed)
  • Go has setter and getter
  • Setter:
func (m *SomeStruct) SetTitle(title string) error {
    // Make validation
    if utf8.RuneCountInString(title) > 10 {
	return errors.New("So much characters")
     }
    m.title = title
    return nil
}
  • Getter:
func (m *SomeStruct)GetTitle() string {
    return m.title
}
  • Getter/setter - for incapsulate fields (and protect it)

Chapter 11. what can you do?: Interfaces

  • Interfaces is like as swift interfaces
  • You declare as:
type MyAwesomeInterface interface {
   func method1()
   func method2()
}
  • In swift we assign interface to object explicity. In Go - don't
  • We only must to provide all methods from interface inside our class
  • To unwrap (get concrete class) from interface:
myInstance := MyAwesomeInterface.(MySuperClass)
myInstance.method3()
myInstance.method4()
...
  • fmt.Print is also firstly read interface (find String() string method inside object)

Chapter 12. back on your feet: Recovering from Failure

  • Use defer to run function anyway (for example, close file if we have some errors in runtime)
  • Use panic to run panic (to panic), and recover for recover from panic
  • Don't use panic+recover as try-except. Is a bad practice

Chapter 13. sharing work: Goroutines and Channels

  • Goroutines - is like as courutines in python
  • To use func as goroutine simple add go before it
  • The main function may completed early then goroutines completed
  • To coordinate goroutines use channels:
func someFunc(channel chan int) {
   ...some logic
   channel <- "hello"
}

func main() {
   channel := make(chan int)
   go someFunc(channel)
   
   fmt.Println(channel) 
}

21.07.2021

Chapter 14. code quality assurance: Automated Testing

  • Create _test.go file and write tests
  • Example:
import "testing"

func TestSomeFunc(t *testing.T) {
  want = "some want value"
  got  = "some got value"

  if want != got {
     t.Error("Want not equal got!")
   }
}
  • The best practice - use TDD - Test Driven Development
  • The best practice also - use TDT - Table driven testing (you create a struct where declare want and got lists)

Chapter 15. responding to requests: Web Apps

  • Use net/http
  • Example:
package main

import (
	"log"
	"net/http"
)

func viewHandler(writer http.ResponseWriter, request *http.Request) {
	message := []byte("hello world")
	_, err := writer.Write(message)
	if err != nil {
		log.Fatal(err)
	}
}

func main()  {
	http.HandleFunc("/hello", viewHandler)
	err := http.ListenAndServe(":8080", nil)
	log.Fatalln(err)
}

Chapter 16. a pattern to follow: HTML Templates

  • Use html/template to render html
  • You provide context in html.Execute (is like as Django render_to_response)
⚠️ **GitHub.com Fallback** ⚠️