It's not long since I really used Go at work, so as a novice, I summarized some common problems and pitfalls
Notes on Pointer use in Go
// 1. Null pointer back reference is illegal package main func main() { var p *int = nil *p = 0 } // in Windows: stops only with: <exit code="-1073741819" msg="process crashed"/> // runtime error: invalid memory address or nil pointer dereference // 2. Text or constant references are also illegal const i = 5 ptr := &i //error: cannot take the address of i ptr2 := &10 //error: cannot take the address of 10
Common built-in functions in Go language
sort
// sort package import "sort" sort.Strings(keys)
close is used for pipeline communication and select is used for switch of communication
type T int func main() { c := make(chan T) close(c) } // select usage var c1, c2, c3 chan int var i1, i2 int select { case i1 = <-c1: fmt.Printf("received ", i1, " from c1\n") case c2 <- i2: fmt.Printf("sent ", i2, " to c2\n") case i3, ok := (<-c3): // same as: i3, ok := <-c3 if ok { fmt.Printf("received ", i3, " from c3\n") } else { fmt.Printf("c3 is closed\n") } default: fmt.Printf("no communication\n") }
len,cap
len is used to return the length or quantity of a type (string, array, slice, map and pipeline);
cap means capacity. It is used to return the maximum capacity of a certain type (it can only be used for slices and map s)
new,make
Both new and make are used to allocate memory: new is used for value types and user-defined types, such as custom structures, and make is used for built-in reference types (slices, map s, and pipes).
They are used like functions, but with types as arguments: new (type), make (type). new (T) assigns a zero value of type T and returns its address, that is, a pointer to type T.
It can also be used for the basic type: V: = new (int). make (T) returns the initialized value of type T, so it does more work than new. New () is a function. Don't forget its parentheses
copy,append
Used to copy and connect slices
panic,recover
Both are used for error handling mechanisms
print,println
The underlying print function. It is recommended to use fmt package in the deployment environment
complex,real,imag
The operation is complex, and there are few usage scenarios
Go does not support function overloading
The main reason why Go language does not support this feature is that function overloading requires redundant type matching, which affects the performance; No overloading means just a simple function scheduling. So you need to give different names to different functions. We usually name functions according to their characteristics
If you need to declare an externally defined function, you only need to give the function name and function signature, not the function body:
func flushICache(begin, end uintptr) // implemented externally
A function can also be used in a declarative manner as a function type, such as:
type binOp func(int, int) int
When Go's map is traversed, the variable address is always the same
Best practice: you can use key and value to read data and address to write data. If you want to assign an address to another map, you need to use temporary variables
kvMap := make(map[int]int) kvMap[0] = 100 kvMap[1] = 101 kvMap[2] = 102 kvMap[3] = 103 for k, v := range kvMap { println(k, &k, v, &v) } // 0 0xc000049e50 100 0xc000049e48 // 1 0xc000049e50 101 0xc000049e48 // 2 0xc000049e50 102 0xc000049e48 // 3 0xc000049e50 103 0xc000049e48
Go traverses the key, and value is the value, not the address
// Version A: items := make([]map[int]int, 5) for i:= range items { items[i] = make(map[int]int, 1) items[i][1] = 2 } fmt.Printf("Version A: Value of items: %v\n", items) // Version B: NOT GOOD! items2 := make([]map[int]int, 5) for _, item := range items2 { item = make(map[int]int, 1) // item is only a copy of the slice element. item[1] = 2 // This 'item' will be lost on the next iteration. } fmt.Printf("Version B: Value of items: %v\n", items2)
The sliced map element should be used by index as in version A. The item obtained in version B is only A copy of the map value, so the real map element is not initialized
Lock and sync package
Concurrent programming is used in most languages to solve the access of multiple threads to critical resources. The classic practice is that only one thread can operate on shared variables at a time. When a variable is changed by a thread (critical area), we lock it. Other threads can't access it until the thread is completed and unlocked. This locking mechanism of Go language is accessed through Mutex in sync package. The following is an example. In addition, there is a read-write lock, RWMutex, in sync package. Its write Mutex method is the same as Mutex, Read Mutex using the following method
Wu Xie, the third master, is a rookie in the field of big data and artificial intelligence. Please pay more attention! [file](https://img-blog.csdnimg.cn/20210808140919157.png)mu sync.Mutex func update(a int) { mu.Lock() a = xxx mu.Unlock() } mu2 sync.RWMutex mu2.RLock() mu2.RUnlock()