I have not been working with Go for a long time, so AS a novice, I have summarized some common problems and pitfalls
Note the use of Pointers in Go
// 1. Null pointer backreference is invalid
package main
func main(a) {
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. Literal 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
Copy the code
Go common built-in functions
sort
/ / sort package
import "sort"
sort.Strings(keys)
Copy the code
Close for pipe communication, select for communication switch
type T int
func main(a) {
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")}Copy the code
Len, cap,
Len is used to return the length or quantity of a type (string, array, slice, map, and pipe);
Cap is capacity and is used to return the maximum capacity of a certain type (for slices and maps only)
The new, make
Both new and make are used to allocate memory: new for value types and user-defined types, such as custom structures, and make for built-in reference types (slices, maps, and pipes).
They are used like functions, but take types as arguments: new (type), make (type). New (T) allocates the zero value of type T and returns its address, which is a pointer to type T.
It can also be used for basic types: 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 the parentheses
Copy, append
Used to copy and join slices
Panic, recover
Both are used for error handling mechanisms
Print and println
The underlying print function, and the FMT package is recommended in a deployment environment
Complex, Real, imag
Operation of complex numbers, the use of a few scenarios
Go does not support function overloading
The main reason why Go does not support this feature is that function overloading requires redundant type matching, which affects performance; No overloading means just a simple function schedule. So you have to give different names to different functions, and we usually give functions names based on their characteristics
If you want to declare an externally defined function, you only need to give the name and signature of the function, not the body of the function:
func flushICache(begin, end uintptr) // implemented externally
Copy the code
Functions can also be used declaratively, as a function type, as in:
type binOp func(int.int) int
Copy the code
The map of Go uses the same variable address all the time
Best practice: Use key and value to read data and address to write data. If you want to assign an address to another map, 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
Copy the code
Go traversal key, 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)
Copy the code
Slice map elements 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 bag
Concurrent programming, found in most languages, is used to deal with multiple threads accessing critical resources. The classic approach is to allow only one thread to operate on shared variables at a time. When a variable is changed by one thread (a critical section), we lock it until the thread has finished executing and unlocked it before other threads can access it. The Go locking mechanism uses Mutex in the Sync package as an example. The way to write a Mutex is the same as the way to read a Mutex
mu sync.Mutex
func update(a int) {
mu.Lock()
a = xxx
mu.Unlock()
}
mu2 sync.RWMutex
mu2.RLock()
mu2.RUnlock()
Copy the code
Check out your profile to follow more.