简体   繁体   中英

Golang function contains anonymous scope

Can someone give me an explanation as to when and why I would use anonymous scope inside a function? (I'm not sure what it's actually called).

I've been given some legacy code to maintain and some of the functions contain this "scope" I have not seen before:

(simplified for demonstration purposes)

func DoSomething(someBoolValue bool) string {
    if someBoolValue {
        // do some stuff
        return "yes"
    }
    {
        // weird scope code
    }
    return "no"
}

I have created a Go Playground to demonstrate some actual code (that throws an error).

It is called Variable scoping and shadowing:

Go is lexically scoped using blocks:

1-The scope of a predeclared identifier is the universe block.
2-The scope of an identifier denoting a constant, type, variable, or function (but not method) declared at top level (outside any function) is the package block.
3-The scope of the package name of an imported package is the file block of the file containing the import declaration.
4-The scope of an identifier denoting a method receiver, function parameter, or result variable is the function body.
5-The scope of a constant or variable identifier declared inside a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl for short variable declarations) and ends at the end of the innermost containing block.
6-The scope of a type identifier declared inside a function begins at the identifier in the TypeSpec and ends at the end of the innermost containing block. An identifier declared in a block may be redeclared in an inner block. While the identifier of the inner declaration is in scope, it denotes the entity declared by the inner declaration.

The package clause is not a declaration; the package name does not appear in any scope. Its purpose is to identify the files belonging to the same package and to specify the default package name for import declarations.

your working sample code:

package main

import (
    "fmt"
)

func main() {
    i := 10
    {
        i := 1
        fmt.Println(i)  // 1
    }
    fmt.Println(i)  // 10
}

output:

1
10

and see: Where can we use Variable Scoping and Shadowing in Go?

{} in Go form a Syntactic Block . Each block defines a new scope. These are same blocks that you use with if and for for example.

With respect to your code, I guess they exist mainly for readability purpose. You can reuse or hide variable defined in the enclosing scope to make use of variables names that maybe declare the code's intent more clearly.

Other than that they can also be used to group a bunch of related statements, again for readability.

To understand their behavior, refer to @Amd's answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM