The type is described in the Golang document:
Named types, with type names such as int, int64, float, string, bool. There are also custom named types.
Non-named type, no type name []string, map[string]string, [4]int. When comparing two named types, the type name must be the same; when comparing named and unnamed types, the underlying type is the same.
There are several forms of declaring variables:
var a int//declaring a variable of type int
var b struct {//declare a struct
Name string
}
var a = 8//declaring variable simultaneous assignment, the compiler automatically infers its data type
var a int = 8//Declaration of simultaneous assignment of a variable
var {//Batch declaration variable, concise
a int
B string
}
Variable initialization
The initialization of a variable can be initialized when a variable is declared, or it can be declared after it is initialized. At this point the VAR keyword is no longer required.
There are several ways to initialize variables, each with a different use scenario:
Declare a temporary variable in a method and assign an initial value
> var tmpstr = ""
> var tmpstr string = ""
> tmpstr: = ""
Direct assignment of variables declared in global
> tmpstr = "<body>"
We see that there are two ways:
var name [Type] = value
If you do not write type, the type is automatically inferred at compile time based on value.
Name: = value
The keyword VAR is omitted here, and I like this way (you can write less code without any harm). But it's important to note that ": =" is declaring and initializing a variable, so the variable must be the first occurrence, and the following initialization is wrong. But be aware that when you assign a value, you want to determine the type you want, and you do not support implicit conversions in go. If you are defining a variable of type float64, write it as V1: =8.0 instead of v1: = 8.
var a int
A: = 8
When I first started this error, always treats ": =" as a general assignment statement
Example
Import (
"FMT"
"Reflect"
)
Type T1 []string
Type T2 []string
Func Main () {
Foo0: = []string{}
Foo1: = t1{}
Foo2: = t2{}
Fmt. Println (reflect. TypeOf (Foo0))
Fmt. Println (reflect. TypeOf (FOO1))
Fmt. Println (reflect. TypeOf (Foo2))
Output:
[]string
Main. T1
Main. T2
Foo0 can be assigned to Foo1, vice versa
Foo1 = Foo0
Foo0 = Foo1
Foo2 cannot be assigned to FOO1
Prog.go:28:cannot use Foo2 (type T2) as type T1 in assignment
Foo1 = Foo2
}
Golang of a variable scope
Testpointer.go
Package Main
Import (
"FMT"
)
var p *int
Func foo () (*int, error) {
var i int = 5
Return &i, Nil
}
Func Bar () {
Use P
Fmt. Println (*P)
}
Func Main () {
P, Err: = foo ()
If Err!= nil {
Fmt. PRINTLN (ERR)
Return
}
Bar ()
Fmt. Println (*P)
}
This code is intended to define a global variable p in a package, initialize p with the return value of Foo (), and use P in bar. Expected Result: 5 is output in bar () and main (). But the result of compilation execution is:
$go Run Testpointer.go
Panic:runtime Error:invalid memory address or nil pointer dereference
[Signal 0xb code=0x1 addr=0x0 PC=0X20D1]
Goroutine 1 [Running]:
Main.bar ()
/users/tony/test/go/testpointer.go:17 +0xd1
Main.main ()
/users/tony/test/go/testpointer.go:26 +0x11c
Goroutine 2 [runnable]:
Runtime.forcegchelper ()
/usr/local/go/src/runtime/proc.go:90
Runtime.goexit ()
/usr/local/go/src/runtime/asm_amd64.s:2232 +0x1
Goroutine 3 [runnable]:
Runtime.bgsweep ()
/usr/local/go/src/runtime/mgc0.go:82
Runtime.goexit ()
/usr/local/go/src/runtime/asm_amd64.s:2232 +0x1
Goroutine 4 [runnable]:
Runtime.runfinq ()
/usr/local/go/src/runtime/malloc.go:712
Runtime.goexit ()
/usr/local/go/src/runtime/asm_amd64.s:2232 +0x1
Exit Status 2
After dinner, continue debugging this code. Why are you crash! The code seems to have no problem, is the go compiler problem, I use the latest 1.4, switch back to 1.3 3, the problem is still ah. It seems to be a code problem, but where is the problem? Add some print statements and look at:
Func bar () {
//use p
FMT. Printf ("%p,%t\n", p, p)//output:0x14dc80, 0x0, *int
fmt. Println (*P)//crash!!!
}
Func Main () {
Fmt. Printf ("%p,%t\n", p, p)//output:0x14dc80, 0x0, *int
P, Err: = foo ()
If Err!= nil {
Fmt. PRINTLN (ERR)
Return
}
Fmt. Printf ("%p,%t\n", p, p)//output:0x2081c6020, 0x20818a258, *int
Bar ()
Fmt. Println (*P)
}
By printing the output, it is found that P (0x2081c6020) from the Foo function and the global variable P (0X14DC80) are not an address, that is to say, not a variable. And from the debug output in bar (), the global variable p is not assigned to the address of variable I in Foo, but is still a nil value when the Foo function returns, resulting in program crash.
OK, no more nonsense, it's time to reveal the truth. The problem is ": =". In this scope of main, we use the
P, Err: = foo ()
The initial understanding is that Golang will define the new variable err,p as the initial defined global variable. But the reality is that for a variable that uses: = = defined, if the new variable p is not in the scope of a defined variable with that same name (this is the global variable p), then Golang will define the variable p to cover the global variable p, which is the real culprit causing the problem.
We'll change the main function to:
Func Main () {
var err error
P, err = foo ()
If Err!= nil {
Fmt. PRINTLN (ERR)
Return
}
Bar ()
}
The results of the execution are completely in line with expectations.