A pit for the Golang variable scope

Source: Internet
Author: User
Tags variable scope
This is a creation in Article, where the information may have evolved or changed.

Near the end of the day to write and debug a piece of Golang code, but the results are always inconsistent with expectations, weird, and still no fruit before work. The code demo is as follows:

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 the 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 supper, continue debugging this code. Why are you still crash? The code seems to have no problem, it is the go compiler problem, I use the latest 1.4, switch back to 1.3.3, the problem is still. It seems to be a problem with the code, 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) and the global variable P (0X14DC80) returned from the Foo function are not an address, that is, not a variable. And from the debug output in bar (), the global variable p is not assigned to the address of the variable i in Foo when the Foo function returns, but remains a nil value, which causes the program to crash.

Well, nonsense, it's time to reveal the truth. The problem is ": =". In the scope of main, we use the

P, Err: = foo ()

The initial understanding is that Golang will define the new variable err,p the global variable that was originally defined. But the reality is that for variables that use: = defined, if the new variable p is not in a scope with the defined variable of the 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 that caused the problem.

Let's change the main function to:

Func Main () {
var err error
P, err = foo ()
If err! = Nil {
Fmt. PRINTLN (ERR)
Return
}
Bar ()
}

The execution result is exactly as expected.

Bigwhite. All rights reserved.

Related Article

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.