Understanding how scopes work in the go language requires some preparatory knowledge of the block, which is described in the article "[code block in Go] (https://studygolang.com/articles/12632)". The scope of an identifier is the source code (and sometimes even all) that binds the identifier with a value, such as a variable, constant, package, and so on. "' Gopackage mainimport" FMT "Func Main () {{V: = 1 {fmt. Println (v)} FMT. Println (v)}//Compile error: "UNDEFINED:V"//FMT. Println (v)} "for experienced engineers, it is easy to determine the output of the program should be this:" >./bin/sandbox11 "The last line of the FMT. Println is commented out because it causes a compilation error. Soon we'll explain why. In a nutshell, the variable v extends beyond its scope by enclosing the curly braces that define its block of code. It is worth mentioning that assigning a new value to a variable does not affect its scope (also known as visibility): ' gov: = 1{v = 2//Assignment FMT. Println (v)}fmt. Println (v) ' Output: ' >./bin/sandbox22 ' and it works differently from the following code: ' gov: = 1{V: = 2//short variable declaration mode FMT. Println (v)}fmt. Println (v) "The output of this code is: ' >./bin/sandbox21 ' scope is closely related to the definition of the identifier (more precisely where the identifier is declared) # # The scope of a variable or constant declaration variable identifier can reach the most inner block of code (either implicitly or explicitly surrounded by curly braces): "' Gofunc Main () {{V: = 1 {fmt. Println (v) {FMT. Println (v)}} fmt. Println (v)}} "This code is 100% valid code, the result is: ' >./bin/sandbox111 ' scope starts with the line of code that the variable is declared. "' Gofunc Main () {FMT. Println (v) V: = 1} "So this code throws a compile error" undefined:v ". A short variable declaration method can declare multiple variables at once: "' Goa, B: = 0, 1 "' But the identifier is valid from where it was declared, so the following is wrong: ' ' Goa, B: = 1, A//undefined: A ' for a short variable declaration, the same scope rule applies:-variable declaration (using the var keyword)-Constant declaration (using Const declaration) in the enclosed variable or constant declaration, the variables or constants take effect from the statements they are declared, without waiting for the entire enclosed code to end, so the following code is valid: "' govar (A = 1//variable Declaration no. 1 B = A//variable declaration No. 2 ) FMT. Println (A, B) "The result is: ' >./bin/sandbox1 1 '" Similarly, if you declare more than one variable in a short way in the enclosed declaration, the Code "Govar (A, B = 1, a)" will also report a compilation error-- "Undefined:a" # # type declaration in terms of scope, a type declaration is the same as a variable or constant-a code block that has been acting on the most inner layer. However, unlike a variable or constant, a type declaration takes effect from where the identity ends, rather than where the type definition code ends. This extra "space" makes the type recursive known as possible: "' Gotype X struct {name string next *x}x: = x{name:" foo ", Next: &x{name:" Bar "}}fmt. Println (X.name) fmt. Println (X.next.name) fmt. Println (x.next.next) ' Output: ' ' > ./bin/sandboxfoobar<nil> ' ' Next field must be a pointer, the following definition is illegal: ' ' Gotype x struct { Name string Next X} ' because the compiler throws a "invalid recursive type X" error, the reason for this error is that when you create type X, the size of the type is computed, and the compiler discovers that the next field of type X is also of type X, A field of the same size that has not been determined, so we will fall into an infinite recursion. However, if it is a pointer class, the compiler will be able to know the size of the pointer type on the specified platform. # # Predefined identifiers have many built-in identifiers:-Type: bool, Int32, Int64, Float64, ...-nil-function: Make, new, panic, ...-constants, such as true/false they have global scope, so they can be used anywhere in the code. Imports when the package is imported, the scope of the name within the package is within the file block. The identifiers within the package can only be referenced by F.ex after the package has been imported correctly. "' go//sandbox.gopackage mainimport" FMT "Func Main () {FMT. Println ("main") f ()}//utils.gopackage MainFunc f () {fmt. Println ("F")} ' "When compiling the above package, the compiler throws an error:" Undefined:fmt in FMT. Println ". # # Top-level identifiers declare variables, constants, types, functions outside any function that are visible within the entire package (scope is the entire package) ' go//sandbox.gopackage mainfunc main () {f ()}//Utils.gopackage Mainimport "FMT" Func f () {fmt. Println ("It works!")} "The above code can compile and run the output: ' >./bin/sandboxit works! ' # # # of functions and methods of the caller, function arguments or return values are accessible only within the body of the function-this is obvious without a code demonstration. # # Masking (shadowing) in the same code block, an identifier cannot be declared two times. But inside the code block, you can re-declare an externally declared identifier (blocks of code that can be nested as layers of onions). If the identifier is re-declared in the inner layer, then the declaration that functions in the code is the innermost statement closest to the code: "gov: =" outer "FMT. Println (v) {V: = "inner" FMT. Println (v) {FMT. Println (v)}}{FMT. Println (v)}fmt. Println (v) "Output:" >./bin/sandboxouterinnerinnerouterouter "# # Reference-[Go Language Specification] (https://golang.org/ref/spec# Declarations_and_scope)-[code blocks in the Go language] (https://studygolang.com/articles/12632)
via:https://medium.com/golangspec/scopes-in-go-a6042bb4298c
Author: Michałłowicki Translator: Moodwu proofreading: polaris1119
This article by GCTT original compilation, go language Chinese network honor launches
This article was originally translated by GCTT and the Go Language Chinese network. Also want to join the ranks of translators, for open source to do some of their own contribution? Welcome to join Gctt!
Translation work and translations are published only for the purpose of learning and communication, translation work in accordance with the provisions of the CC-BY-NC-SA agreement, if our work has violated your interests, please contact us promptly.
Welcome to the CC-BY-NC-SA agreement, please mark and keep the original/translation link and author/translator information in the text.
The article only represents the author's knowledge and views, if there are different points of view, please line up downstairs to spit groove
257 Reads