golang novices are not aware of minor problems that may occur

  • 2020-06-12 09:19:13
  • OfStack

go profile

Philosophy of language

The C language is purely procedural, depending on the historical context in which it was produced. Java is a radical proponent of objectivism, typically intolerant of isolated functions. However, Go language does not deny any one. Instead, it USES a critical and absorbing perspective to comb all programming ideas once and integrate the strengths of all families. However, it is always vigilant about the complexity of features, and tries its best to maintain the conciseness of language features and strive to be small and refined

The Go language opposes function and operator overloading (overload), while C++, Java, and C# all allow functions or operators with the same name, as long as they have different argument lists.

Second, the Go language supports combinations of classes, class member methods, and classes, but opposes inheritance, virtual functions (virtual function), and virtual function overloading. Specifically,Go also provides inheritance, but with a combined grammar

Recently, I have been sorting out the youdao cloud notes I took when I was writing programs and studying. I have found some interesting points to share with you. Please point out any mistakes

1. The closure defer

Closures (anonymous functions)


func test(){
 i, n := 1 ,2;
 defer func(a int){
  fmt.Println("defer:", a , n); //n Referenced by closure 
 }(i) // copy i The value of the 
 i , n = i+1,n+2;
 fmt.Println(i , n);
}

Let's take a look at the results:


2 4
defer: 1 4

Why is that? Because the closure copies the original object pointer, a delayed reference occurs. We need to be aware of this problem when using closures, as we do in the for loop.

2. Map

I saw a question in the forum a while ago


type Data struct{
 AABB [2]float64
}
var m map[string]Data = make(map[string]Data,1)
m["xxx"] = Data{}
m["xxx"].AABB[0]=1.0
m["xxx"].AABB[1]=2.0<br data-filtered="filtered"># The above code go build  Failed, error message cannot assign to m["xxx"].AABB[0]

This is the answer given by one netizen


type Data struct{
 AABB [2]float64
} 
m := make(map[string]*Data,1)
m["xxxx"] = Data{}
m["xxxx"].AABB[0] = 1.0
m["xxxx"].AABB[1] = 2.0
# There you go, yours  m["xxxx"]  It returns a value, not a value 1 A variable with a desirable address 

This netizen's answer can compile success, but not desirable, he made a lot of novice are easy to appear

why? The map element attribute in Golang is designed to be read-only and is not expected to be modified, and the value retrieved from map is also a temporary copy. And map is an hash structure, when hash is expanded, the storage location of key values will change. If at this point we modify m["xxxx"].AABB [0] = 1.0, we don't know what the pointer will say. You may be interested in looking at the Go Hashmap memory layout and implementation

This is best if we want to modify it


type Data struct{
 AABB [2]float64
}
m := make(map[string]*Data,1)
m["xxxx"] = &Data{}
d  : = m["xxxx"]
d.AABB[0] = 1.0
d.AABB[1] = 2.0
m["xxxx"] = d

3. nil

Let's start with a snippet of code. This is not a common scenario, of course, but it gives us a better understanding of nil


func t(){
 var i *int = nil;
 var n interface{} = i;
 fmt.Println(n==nil); //false
}

Many students may wonder why nil is different. Let's first look at the structure of pointer and interface and the structure when pointer and interface are nil


uintptr
type interfaceStruct struct {
  v *_value //  The actual value 
  t *_type //  Type information for the actual value 
}
uintptr(0) == nil
type interfaceStruct struct {
  v:uintptr(0)
  t:uintptr(0)
} == nil

From this we can see that nil is actually the zero value of the pointer interface

At this point, it's easy to explain why flase is so easy


func t(){
 var i *int = nil; // (*int)nil
 var n interface{} = i; // interace{}((*int)nil)
 fmt.Println(n==nil); // type interfaceStruct struct {
                 //  v: uintptr(0),
                 //  t: (*int)
                 // }
}

The official documents specify that there are slice, map, channel, function types that can be nil.

Some of you may ask why there is no error type. It is because error is the default interface method of the program


type error interface { 
 Error() string 
}  

conclusion


Related articles: