This is a creation in Article, where the information may have evolved or changed.
The go language is a simple but profound language. However, even if it is the simplest C language, can be summed up a "C traps and defects", not to mention the go language. Many of the pits in the go language are not really the problem of go itself. Some mistakes you can make in other languages, such as scopes, some errors are caused by the features of the Go language that are not understood, such as range.
In fact, if you are learning the go language carefully to read official documents, Wikipedia, mailing lists or other celebrity blogs like Rob Pike, reports, then many of the pits mentioned in this article can be avoided. But not everyone will learn from the basics, for example, translators like to simply and rudely write programs directly in the Go language. If you are like a translator, then you should read this article: This avoids wasting too much time in debugging programs.
This article divides 50 pits into the following three levels in terms of usage and ease of use: "Beginner entry Level", "Beginner Level", "Beginner into Class".
1 "{" cannot be placed on one line alone
Level: Beginner Entry level
The Go language designer certainly has a dubious relationship with the C language designer (K&r), because the K&r format in the C language is carried forward in the go language. In most languages, the opening parenthesis in curly braces can be placed casually: the C language must be formatted in the K&R format, and the opening parenthesis will be placed at the end of the previous line. But in the go language, the opening parenthesis must be forced to be placed on a single line. This rule is due to "automatic semicolon injection" (automatic semicolon injection).
Error code:
Package Main
Import "FMT"
Func Main ()
{//error, can ' t has the opening brace on a separate line
Fmt. Println ("Hello there!")
}
Error message:
/tmp/sandbox826898458/main.go:6: Syntax error:unexpected semicolon or newline before {
Fix code:
Package Main
Import "FMT"
Func Main () {
Fmt. Println ("works!")
}
2 No defined variables are used
Level: Beginner Entry level
If there are unused variables in the code, the code is compiled with an error. Go requires that all variables declared in the code need to be used, except, of course, global variables.
The parameters of the function can also be declared and not used.
Calls to undeclared variables can also cause compilation to fail. Like the C language, the Go compiler is also a woman, and you should try to be satisfied with what he says.
Error code:
Package Main
var Gvar int//not An error
Func Main () {
var one int//error, unused variable
Both: = 2//error, unused variable
var three int//error, even though it ' s assigned 3 on the next line
three = 3
Func (unused string) {
Fmt. Println ("Unused Arg. No Compile Error ")
} ("What?")
}
Error message:
/tmp/sandbox473116179/main.go:6: one declared and not used/tmp/sandbox473116179/main.go:7: both declared and not used/tmp /sandbox473116179/main.go:8: Three declared and not used
Fix code:
Package Main
Import "FMT"
Func Main () {
var one int
_ = One
Both: = 2
Fmt. Println (both)
var three int
three = 3
one = three
var four int
four = Four
}
Of course, you can also consider deleting variables that are not used.
3 Unused Packages
Level: Beginner Entry level
When you import a package, if you do not use the package, or the function/interface/data structure/variables in the package, it will fail to compile.
If you really confirm that you want to introduce a variable but not use it, we can use the "" identifier to sit on the tag to avoid compilation failure. The "" identifier indicates that these packages are introduced in order to obtain the side effects of these packages.
Error code:
Package Main
Import (
"FMT"
"Log"
"Time"
)
Func Main () {
}
Error message:
/tmp/sandbox627475386/main.go:4: Imported and not used: "FMT"
/tmp/sandbox627475386/main.go:5: Imported and not used: "Log"
/tmp/sandbox627475386/main.go:6: Imported and not used: "Time"
Fix code
Package Main
Import (
_ "FMT"
"Log"
"Time"
)
var _ = log. Println
Func Main () {
_ = time. Now
}
4 short variable declarations can only be used inside a function
Level: Beginner Entry level
Error code:
Package Main
MyVar: = 1//error
Func Main () {
}
Error message:
/tmp/sandbox265716165/main.go:3: non-declaration statement outside function body
Fix code:
Package Main
var myvar = 1
Func Main () {
}
5 cannot re-assign a variable using a thin assignment statement
Level: Beginner Entry level
You cannot re-assign a single variable using a thin assignment statement, but you can assign multiple variables at the same time using a thin assignment statement.
Also, the redefined variables must be written in the same block of code.
Error message:
Package Main
Func Main () {
One: = 0
One: = 1//error
}
Error message:
/tmp/sandbox706333626/main.go:5: No new variables on left side of: =
Fix code:
Package Main
Func Main () {
One: = 0
One, both: =
One,two = Two,one
}
6 implicit variable (scope)
Level: Beginner Entry level
Like the C language, the Go language also works, and a variable is scoped to just one block of code. Although a thin assignment statement is simple, note the scope.
Package Main
Import "FMT"
Func Main () {
x: = 1
Fmt. PRINTLN (x)//print 1
{
Fmt. PRINTLN (x)//print 1
x: = 2
Fmt. PRINTLN (x)//Print 2
}
Fmt. PRINTLN (x)//print 1 (not 2)
}
Even for experienced developers, this is a deep hole that will fall in unnoticed.
7 You cannot use nil to assign a value to a variable unless specifically specified
Level: Beginner Entry level
Nil can be used as a "null" for interface, function, pointer, map, slice, and channel. However, if not specifically specified, the Go language does not recognize the type, so it will error.
Error message:
Package Main
Func Main () {
var x = nil//error
_ = X
}
Error message:
/tmp/sandbox188239583/main.go:4: Use of untyped nil
Fix code:
Package Main
Func Main () {
var x interface{} = Nil
_ = X
}
8 Nil values for Slice and MAP
Level: Beginner Entry level
Slice with an initial value of nil can be "added", but the "add" operation for the MAP will cause a runtime panic. (") panic.
Fix code:
Package Main
Func Main () {
var s []int
s = Append (s,1)
}
Error message:
Package Main
Func Main () {
var m map[string]int
m["one"] = 1//error
}
9 Map Fixed length
Level: Beginner Entry level
You can specify the length of the map when you create the map, but you cannot use the CAP () function to re-specify the size of the map at run time, and the map is fixed-length.
Error message:
Package Main
Func Main () {
M: = Make (map[string]int,99)
Cap (m)//error
}
Error message:
/tmp/sandbox326543983/main.go:5: Invalid argument m (type Map[string]int) for cap
10 string cannot be nil
Level: Beginner Entry level
All developers may step on the pit, in C language can be char *string=null, but the Go language cannot be assigned to nil.
Error message:
Package Main
Func Main () {
var x string = Nil//error
if x = = Nil {//error
x = "Default"
}
}
Compile Errors:
/tmp/sandbox630560459/main.go:4: Cannot use nil as type string in Assignment/tmp/sandbox630560459/main.go:6: Invalid Ope Ration:x = = Nil (mismatched types string and nil)
Fix code:
Package Main
Func Main () {
var x string//defaults to "" (zero Value)
if x = = "" {
x = "Default"
}
}
The array in the 11 parameter
Array Function Arguments
Level: Beginner Entry level
For C and C + + developers, arrays are pointers. To pass an array to a function is to pass the memory address, the modification of the array is the modification of the original address data. However, in the Go language, the passed array is not a memory address, but a copy of the original array, so it is not possible to pass the array method to modify the original address of the data.
Package Main
Import "FMT"
Func Main () {
x: = [3]int{1,2,3}
Func (arr [3]int) {
Arr[0] = 7
Fmt. Println (arr)//prints [7 2 3]
} (x)
Fmt. PRINTLN (x)//prints [1 2 3] (not OK if you need [7 2 3])
}
If you need to modify the data of the original array, you need to use an array pointer (array pointer).
Package Main
Import "FMT"
Func Main () {
x: = [3]int{1,2,3}
Func (arr *[3]int) {
(*arr) [0] = 7
Fmt. Println (arr)//prints &[7 2 3]
} (&X)
Fmt. PRINTLN (x)//prints [7 2 3]
}
Or you can use Slice,
Package Main
Import "FMT"
Func Main () {
x: = []int{1,2,3}
Func (arr []int) {
Arr[0] = 7
Fmt. Println (arr)//prints [7 2 3]
} (x)
Fmt. PRINTLN (x)//prints [7 2 3]
}
12 using a range of Slice and Array will result in unexpected results
Level: Beginner Entry level
If you are familiar with for-in and foreach in other languages, the range used in Go is completely different. Because the range will return two values each time, the first value is the number in Slice and Array, and the second is the corresponding data.
Error code:
Package Main
Import "FMT"
Func Main () {
x: = []string{"A", "B", "C"}
For V: = range x {
Fmt. Println (v)//prints 0, 1, 2
}
}
Fix code:
Package Main
Import "FMT"
Func Main () {
x: = []string{"A", "B", "C"}
For _, V: = range x {
Fmt. Println (v)//prints A, B, c
}
}