Chapter 2 Program Structure
2.1 Naming
focus
- Function names, variable names, constant names, type names, statement labels, and package names
- Begins with a letter (Unicode letter) or underscore, and any number of letters, numbers or underscores, uppercase and lowercase letters are different.
- Keywords (25)
break default func interface select case defer go map struct chan else goto package switch const fallthrough if range type continue for import return var
- Predefined names (30+), these are not keywords, you can reuse them in definitions
内建常量: true false iota nil 内建类型: int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr float32 float64 complex128 complex64 bool byte rune string error 内建函数: make len cap new append copy close delete complex real imag panic recover
- Scope: internal definition is valid inside; external definition package is valid, the name starts withcapitalVisible outside the package.
fmt
For example :Print
can befmt
accessed outside the package. - Name length: In principle, there is no regulation, but the interior is as short as possible; if the scope is large and the life cycle is relatively long, a long name will be more meaningful.
- Naming method: use "camel case" naming. For example: the standard library has functions named
QuoteRuneToASCII
andparseRequestLine
such, but such names are generally notquote_rune_to_ASCII
usedparse_request_line
. Whereas acronyms likeASCII
and avoid mixed case, they might be called , or , but won't be .HTML
htmlEscape
HTMLEscape
escapeHTML
escapeHtml
2.2 Declaration
focus
- Type declaration: Four types of declaration statements:
var
,const
,type
andfunc
correspond to variables, constants, types, and function entity objects respectively. - The order of the declaration statements of various types of package-level types, variables, constants, and functions does not matter,inside the functionThe name must be declared before it can be used.
- Function declaration: function name, parameter list, return value list, function body of function definition.
2.3 Variables
focus
var 变量名字 类型 = 表达式
, either "type" or "= expression" can be omitted, if it is not initialized, it will be initialized aszero value。- Zero value:
Value -> 0
Boolean -> false
string -> empty string
Interface or reference type (including slice, map, chan and function) ->
aggregation type such as nil array or structure -> zero value corresponding to each element or field
- Declare a set of variables, or be initialized by multiple return values returned by a function
var i, j, k int // int, int, int var b, f, s = true, 2.3, "four" // bool, float64, string var f, err = os.Open(name) // os.Open returns a file and an error
2.3.1 Short variable declaration
focus
- Example, a variable or set of variables:
i := 100 i, j := 0, 1
:=
is a variable declaration statement,=
but a variable assignment operation- The following code declares in and err first, then only out is declared for the second time, and the declared err is only assigned; there must be at least one new variable in the short variable declaration;
编译通过 in, err := os.Open(infile) // ... out, err := os.Create(outfile)
编译失败 f, err := os.Open(infile) // ... f, err := os.Create(outfile) // compile error: no new variables
2.3.2 Pointers
focus
var x int
&x
Expression (takex
the memory address of the variable), the data type corresponding to the pointer is*int
,*p
the expression corresponds to the value of the variable pointed to by the p pointer- In the Go language,It is also safe to return the address of a local variable in a function, the following code is valid, but the address returned each time changes and the value remains unchanged
var p = f() func f() *int { v := 1 return &v }
- In the Go language, you can't use pointers
++
or--
,*p++
justIt just increases the value of the variable pointed to by p, and does not change the p pointer! ! ! - Pointers are the key technology to implement the flag package in the standard library
Common libraries and methods
flag
flag.Bool()
flag.String()
flag.Parse()
flag.Args()
2.3.3 new function
focus
new(T)
Will create anT
anonymous variable of type, initialize it toT
the zero value of type, and return the variable address, returning a pointer of type*T
.- There is no difference between creating variables with new and creating variables with ordinary variable declaration statements. The following are equivalent:
func newInt() *int { return new(int) } func newInt() *int { var dummy int return &dummy }
- If both types are empty, that is to say the types have a size of 0, for example
struct{}
and[0]int
, it is possible to have the same address. (Please be careful to use a type with a size of 0, because if the size of the type is 0, it may cause the automatic garbage collector of the Go language to behave differently. For details, please refer to the relevant documentation of the runtime.SetFinalizer function) new
For predefined functions, not keywords, willnew
redefine
func delta(old, new int) int { return new - old }
2.3.4 The life cycle of variables
focus
- Package-level variables: the program running cycle; local variables: from the beginning of the declaration to the end of no longer reference, the input and return are all local variables;
- The right parenthesis of the function can be indented on another line. In order to prevent compilation errors caused by the compiler automatically inserting a semicolon at the end of the line, you can explicitly insert a comma after the parameter variable at the end, as follows:
img.SetColorIndex( size+int(x*size+0.5), size+int(y*size+0.5), blackIndex, // 最后插入的逗号不会导致编译错误,这是Go编译器的一个>特性 ) // 小括弧另起一行缩进,和大括弧的风格保存一致
- The Go compiler automatically chooses whether to allocate storage for local variables on the stack or on the heap, but perhaps surprisingly, this choice is not determined by how the variable is declared
var
or declarednew
- Escaping behavior for variables
2.4 Assignment
focus
- Increment and decrement are statements, not expressions, so
x = i++
expressions like
2.4.1 Tuple assignment
focus
- Simultaneously update the value on the left side of the variable
x, y = y, x a[i], a[j] = a[j], a[i]
- Expressions that produce multiple values, or return a Boolean value, are often referred to as ok,map lookup (§4.3)、type assertions (§7.10),orChannel reception (§8.4.2)Appearing on the right-hand side of an assignment statement, they both may produce two results, with an additional boolean result indicating whether the operation was successful:
f, err = os.Open("foo.txt") // function call returns two values v, ok = m[key] // map lookup v, ok = x.(T) // type assertion v, ok = <-ch // channel receive
- : When map lookup (§4.3), type assertion (§7.10) or channel reception (§8.4.2) appear on the right side of an assignment statement, it does not necessarily produce two results, and may only produce one result. For the case where the value produces a result, a zero value will be returned when the map lookup fails, a runtime panic exception will be sent when the type assertion fails, and a zero value will be returned when the channel fails to receive (blocking is not considered a failure), for example:
v = m[key] // map查找,失败时返回零值 v = x.(T) // type断言,失败时panic异常 v = <-ch // 管道接收,失败时返回零值(阻塞不算是失败) _, ok = m[key] // map返回2个值 _, ok = mm[""], false // map返回1个值 _ = mm[""] // map返回1个值
2.4.2 Assignability
focus
- The type must match exactly, nil can be assigned to any variable of pointer or reference type
- The ability to compare two values
==
for!=
equality with or is also related to assignability: for an equality comparison of values of any type, the second value must be assignable to the variable of the first value type
2.5 types
focus
type 类型名字 底层类型
Type declaration statements generally appear at the package level, so if the first character of the newly created type name is capitalized, it can also be used in external packages- Each type
T
has a conversion operation,T(x)
which is used tox
convert it intoT
a class. IfT
it is
a pointer type, it may need to be wrapped in parenthesesT
. For example(*int)(0)
, this conversion operation is only allowed when the underlying basic types of the two types are the same.
2.6 Packages and files
focus
- The suffix of the directory path where the package is located is the import path of the package; for example,
gopl.io/ch1/helloworld
the directory path corresponding to the package is$GOPATH/src/gopl.io/ch1/helloworld
- Each package corresponds to a separate namespace;
image.Decode
orutf16.Decode
different forms - If a name starts with an uppercase letter, the name is exported
- Package-level names, types and constants declared in one file are also directly accessible from other source files in the same package
- Comments preceding a package declaration are package comments (§10.7.4). A package usually has only one source file with package comments. If there are multiple package comments, they will be linked into one package comment. If it is very large, it will usually be placed in a separate doc.go file
2.6.1 Import package
focus
- Each package also has a package name, which is generally a short name (the package name is not required to be unique)
golang.org/x/tools/cmd/goimports
Import tool that can automatically add or remove imported packages as needed
2.6.2 Package initialization
focus
- The initialization of the package resolves the dependency order of the package-level variables, and initializes them sequentially according to the order of appearance
var a = b + c // a 第三个初始化, 为 3 var b = f() // b 第二个初始化, 为 2, 通过调用 f (依赖c) var c = 1 // c 第一个初始化, 为 1 func f() int { return c + 1 }
- Some table data initialization is not a simple assignment process, and a special init initialization function can be used to simplify the initialization work. Each file can contain multiple init initialization functions, which are automatically called in the order in which they are declared when the program starts to execute. Each package will only be initialized once
func init() { /* ... */ }
- The range loop only uses the index, so the unused value part can be omitted, the following is equivalent:
for i := range pc {}
for i, _ := range pc { }
2.7 Scope
focus
- A program may contain multiple declarations with the same name, as long as they have different scopes. Example: You can declare a local variable with the same name as a package-level variable; you can declare the name of a function parameter as
new
, although the built-innew
is globally scoped. Local declarations override global declarations; if
,switch
the condition part is an implicit lexical domain, and each is the lexical domain of each branch- At the package level, the order of declarations does not affect the scope, so an earlier declaration can refer to itself or to a later declaration, which allows us to define types or functions that are nested or recursive.
Common libraries and methods
os
os.Getwd
log
log.Fatalf
unicode
unicode.ToUpper