Description of type comparison and type assignment in Golang

Source: Internet
Author: User
Tags variable scope

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.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.