這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
This post is about declaration scopes and shadowing in Go.
package mainimport "fmt"func f(x int) {for x := 0; x < 10; x++ {fmt.Println(x)}}var x intfunc main() {var x = 200f(x)}
This program declares x
four times. All four are different variables because they exist in different scopes.
package mainimport "fmt"func f() {x := 200fmt.Println("inside f: x =", x)}func main() {x := 100fmt.Println("inside main: x =", x)f()fmt.Println("inside main: x =", x)}
In Go the scope of a declaration is bound to the closest pair of curly braces, {
and }
. In this example, we declare x
to be 100 inside main, and 200 inside f
.
What do you expect this program will print?
package mainimport "fmt"func main() {x := 100for i := 0; i < 5; i++ {x := ifmt.Println(x)}fmt.Println(x)}
There are several scopes in a Go program; block scope, function scope, file scope, package scope, and universe scope. Each scope encompasses the previous. What you are seeing is called shadowing.
var x = 100func main() { var x = 200 fmt.Println(x)}
Most developers are comfortable with a function scoped variable shadowing a package scoped variable.
func f() { var x = 99 if x > 90 { x := 60 fmt.Println(x) }}
But a block scoped variable shadowing a function scoped variable may be surprising.
The justification for a declaration in one scope shadowing another is consistency, prohibiting just block scoped declarations from shadowing another scope, would be inconsistent.
Related posts:
- Stupid Go declaration tricks
- Associative commentary
- Channel Axioms
- What is the zero value, and why is it useful ?