"Go Language Lesson 1" Course Study Notes (7)

Code blocks and scope: how to ensure that variables are not shadowed?

  • What is variable shadowing?
    package main
    
    import (
    	"fmt"
    
    	"github.com/google/uuid"
    	"github.com/sirupsen/logrus"
    )
    
    func main() {
          
          
    	fmt.Println("hello, world")
    	logrus.Println(uuid.NewString())
    	var (
    		a int    = 10
    		b int8   = 6
    		s string = "hello"
    		c rune   = 'A'
    		t bool   = true
    	)
    	var res int = a * int(b)
    	fmt.Println(res)
    	fmt.Println(s)
    	var res2 rune = rune(res) / c
    	fmt.Println(res2)
    	fmt.Println(t)
    
    	var a1 = 11
    	fmt.Println("a1 =", a1)
    	foo(5)
    	fmt.Println("after calling foo, a1 =", a1)
    }
    
    func foo(n int) {
          
          
    	a1 := 1
    	a1 += n
    }
    
  • The output is as follows:
    hello, world
    time="2023-08-17T16:04:43+08:00" level=info msg=712d41da-1efa-42eb-91f0-5a3ee017cc0e
    60
    hello
    0
    true
    a1 = 11
    after calling foo, a1 = 11
    
    • In this code, the value of the package-level variable a1 does not change before and after the function foo is called. This is because, although the variable a1 is also used in the foo function, the variable a1 in the foo function covers the external package-level variable a1, which makes the package-level variable a1 not participate in the logic of the foo function, so there is no change up.
    • Variable shadowing is one of the most common coding mistakes that Go developers make in their daily development work. It is low-level and not easy to find, and often leads you into a long debugging process.

Code Blocks and Scope

  • A code block in Go language is a sequence of declarations and statements enclosed in a pair of braces. If there is no statement or other statement inside a pair of braces, we call it an empty code block. Go code blocks support nesting, we can embed multiple levels of code blocks in a code block.
  • Each identifier has its own scope, and the scope of an identifier refers to the source code area where the identifier can be effectively used after it is declared.
  • The scope of an identifier declared in an outer code block includes all inner code blocks.
    • The scope of an identifier corresponding to a constant, type, variable, or function (not including a method) in a package top-level declaration is the package code block.
    • When a package A imports another package B, package A can only use the exported identifier (Exported Identifier) ​​in the imported package B.
    • In the function/method body, the principle of identifier scoping is simpler, because we can clearly delimit the scope of an identifier by means of visually visible paired curly braces.
    • The scope of the identifier corresponding to the constant or variable declared inside the function begins at the end of the constant or variable declaration statement and ends at the end of the innermost containing block.

avoid variable shadowing

  • Go officially provides the go vet tool, which can be used to perform a series of static checks on Go source code. Prior to Go version 1.14, variable shadow checking was supported by default. After Go version 1.14, the plugin for variable shadow checking needs to be installed separately: go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest.
    • Once installed, we can scan the code with go vet and check for variable shadowing issues.
    • The command to perform the check is as follows: go vet -vettool=$(which shadow) -strict xxx.go.
    • Tools can indeed assist in detection, but they are not omnipotent. They cannot exhaustively find out all the problems in the code, so it is still necessary to have a deep understanding of the concepts of code blocks and scope, and actively avoid all masking problems in daily coding as much as possible.

Guess you like

Origin blog.csdn.net/fangzhan666/article/details/132343318