mirror of
https://github.com/wahyd4/knowledge.git
synced 2026-08-09 05:06:28 +10:00
4.4 KiB
4.4 KiB
Language
pass pointer or value
- value: Variable must not be modified
- Variable is a large struct then prefer pointer
- Variable is a map or slice then prefer value
- Passing by value often is cheaper
struct
- make
make(T, args) -> T
- new
new(T) -> *T
- a := T{}
array
[]string
[]string{"a", "b"}
[...]string{"a","b"}
Array has a exactly length, can't be modified.
slice
- Auto increment length
new([]int)
make([]int, 2, 5)
- nil is a valid slice which length is
0
Go routine
- you can run more goroutine vs thread
- go routine have a faster start up time than thread
- go routine come with built-in primitives to communicate safely by using channels
Closure
Channel
- Normal channel
messages := make(chan string)
// _Send_ a value into a channel using the `channel <-`
go func() { messages <- "ping" }()
// channel. Here we'll receive the `"ping"` message
msg := <-messages
- buffered channel
ch := make(chan Task, 3)
Sync
atomic
Mutex
- sync.Mutex()
- mutex.Lock()
- mutx.Unlock()
RWMutex
A RWMutex is a reader/writer mutual exclusion lock. The lock can be held by an arbitrary number of readers or a single writer. The zero value for a RWMutex is an unlocked mutex.
In other words, readers don't have to wait for each other. They only have to wait for writers holding the lock.
string literals
`aaa bbb ccc`
panic / recover
sync.Map is concurrent/ thread safe map, normal map isn't
m := new(sync.Map)
m.Store("a", "b")
value, ok := m.Load("a")
Frameworks
db
- xorm
- gorm
web
- beego
- mux
- gin
- go kit
- full stack micro service framework like spring boot
tools
- profiler
- go-wrk(wrk)
- a http benchmark tool
- go-torch
- Stochastic flame graph profiler
- go-wrk(wrk)
- test
- Testify http://github.com/stretchr/testify
- Ginkgo http://onsi.github.io/ginkgo/
Tips
slice
- byte* array //actual data
- uintgo len
- uintgo cap
map
- implement by hash table
- slice can't be the key of a map, but sized array could.
var a map[[2]int]string
Go has no generics
- performance
- complexity
- If C++ and Java are about type hierarchies and the taxonomy of types, Go is about composition.
- How to solve
- use interface
- use type assertions
- use reflection
Modify item in range
- use the array index instead of the value
for _, e := range array {
e.field = "foo"
}
for idx, _ := range array {
array[idx].field = "foo"
}
merge two array
- a = append(a, b…)
- must add … to b, otherwise you can only add one item
error handling
- error type assertion
if serr, ok := err.(*json.SyntaxError); ok {}
-
better error handling
- custom error type
type appError struct {
Error error
Message string
Code int
}
- concat error check
if err1() != nil || err2() != nil {}
- some error constants
errNotFound = errors.New("Item not found")
switch err {
case errNotFound:
}
date format
t := time.Now()
fmt.Println(t.String())
fmt.Println(t.Format("2006-01-02 15:04:05"))
- var _ InterfaceX = &InterfaceXImplementation{}
- make sure InterfaceX’s implementation works
reference types in go
- map
- channel
- slice
value types
- Array
Read file line by line
package main
import (
"bufio"
"fmt"
"log"
"os"
)
func main() {
file, err := os.Open("/path/to/file.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
}
commands
test
- go test ./...
- run all tests in current directory and all of its subdirectories
- go test foo/...
- run all tests with import path prefixed with foo/:
- go test foo...
- run all tests import path prefixed with foo:
- go test ...
- run all tests in your $GOPATH:
REPL
REPL stands for read eval print loop, basically it just like the irb in Ruby.
Wiki: https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop