Go Language Study Notes - Chapter 10 Package Mechanism and Package Organization Structure (The Go Programming Language)

Chapter 10 Package Mechanism and Package Organizational Structure

  • Chapters 10 and 11 mainly talk about how to organize a project into a series of packages, how to obtain, build, test, performance test, analyze, write documents, and share these packages.

10.1 Package Introduction

focus

  • The lightning-fast compilation speed of the Go language is mainly due to three language features:
    • First, all imported packages must be explicitly declared at the beginning of each file, so that the compiler does not have to read and analyze the entire source file to determine package dependencies.
    • The second point is to prohibit the circular dependency of the package, because there is no circular dependency, the dependency of the package forms a directed acyclic graph, and each package can be compiled independently, and it is likely to be compiled concurrently.
    • The third point is that the target file of the compiled package not only records the export information of the package itself, but also records the dependencies of the package.

10.2 Import path

focus

  • Each package is located by an import path identified by a globally unique string.

10.3 Package Declaration

focus

  • The default package name is the last segment of the package import path name, so even if two packages have different import paths, they may still have the same package name. For example, the packages math/rand and crypto/rand both have rand.
  • The default package name generally follows the convention of the last segment of the import pathname, with three exceptions:
    • 1. The package corresponds to an executable program, that is, the main package. At this time, the import path of the main package itself is irrelevant. After the package is compiled, the linker must be called to generate an executable program.
    • 2. There may be some Go source files whose file names are suffixed with test.go in the directory where the package is located, and the package names declared by these source files
      _testare . Directories prefixed with or go testare ignored_.
    • 3. Some management tools that rely on the version number will append the version number information after the import path, such as "gopkg.in/yaml.v2". In this case the package name does not contain the version number suffix, but yaml.

10.4 Import statement

focus

  • The following two ways are equivalent:
import "fmt"
import "os"
import (
"fmt"
"os"
)
  • Imported packages can be grouped by adding blank lines; usually packages from different organizations are grouped separately. The order in which the packages are imported does not matter, but within each group they are generally sorted according to string order. (Both the gofmt and goimports tools can independently sort packages imported by different groups.)
import (
"fmt"
"html/template"
"os"
"golang.org/x/net/html"
"golang.org/x/net/ipv4"
)
  • If we want to import two packages with the same name at the same time, such as math/rand package and crypto/rand package, then the import statement must specify a new package name for at least one package with the same name to avoid conflicts. This is called renaming of imported packages. Renaming of imported packages only affects the current source file.
import (
"crypto/rand"
mrand "math/rand" // alternative name mrand avoids conflict
)
  • Import package renaming is a useful feature:
    • resolve name conflicts
    • Replace potentially unwieldy package names in some auto-generated code with a short name.
    • Can help avoid conflicts with local common variable names.
  • The build tool of the Go language will report an error when a package is imported circularly.

10.5 Anonymous import of packages

focus

  • Just importing a package without using the imported package will result in a compilation error
  • Renaming the imported package with an underscore _blank identifier indicates that the package cannot be accessed. This will help us to calculate the initialization expression of the package-level variable and execute the init initialization function of the imported package. This is called anonymous import of the package.
import _ "image/png" // register PNG decoder

Common libraries and methods

  • image.Decode image.RegisterFormat
  • jpeg.Encode jpeg.Options
  • os.Exit

10.6 Packages and Naming

focus

  • Some conventions about naming packages and members unique to the Go language
    • When creating a package, generally use short package names, but not so short that they are difficult to understand. For example, don't name a generic package like imageutil or ioutilis util
    • Try to avoid package names that may be frequently used for local variables, which may lead to renaming
      imported packages, such as the path package seen earlier
    • Package names generally use the singular form. The bytes, errors, and strings of the standard library use plural forms to avoid conflicts with predefined types, and go/types is also used to avoid conflicts with the type keyword.
    • Avoid package names that have other meanings. For example, our temperature conversion package temp in Section 2.5 is almost a synonym for temporary variables; temperature is used as the package name, although the name does not express the real purpose of the package; the tempconv package name is similar to the strconv standard package, which is recommended
    • When designing a package, you need to consider how the two parts of the package name and the member name fit together. For example, bytes.Equal, flag.Int, http.Get, json.Marshal
    • Some other packages may only describe a single data type, such as html/template and math/rand, etc., only expose a main data structure and its related methods, and a function named New is used to create an instance. This can lead to duplication of some names, such as template.Template or rand.Rand
    • There are also packages like net/http that have a lot of names and few types of data types, because they all perform a complex composite task. Despite the large number of types and more functions, the most important member names in the package are simple and clear: Get, Post, Handle, Error, Client, Server, etc.

10.7 Tools

focus

  • Specific features of the Go toolbox, including how to download, format, build, test, and install programs written in Go
  • Toolbox features:
    • A package manager for tasks such as querying packages, computing package dependencies, and downloading them from remote version control systems
    • A build system that computes file dependencies and then invokes the compiler, assembler, and linker to build the program
    • A driver for unit testing and benchmarking
  • The most commonly used commands for go:
$ go
...
build compile packages and dependencies
clean remove object files
doc show documentation for package or symbol
env print Go environment information
fmt run gofmt on package sources
get download and install packages and dependencies
install compile and install packages and dependencies
list list packages
run compile and run Go program
test test packages
version print Go version
vet run go tool vet on packages
Use "go help [command]" for more information about a command.

10.7.1 Workspace structure

focus

  • For most Go language users, you only need to configure an environment variable called GOPATH to specify the current working directory. When you need to switch to a different workspace, just update GOPATH.
  • The workspace directory corresponding to GOPATH has three subdirectories:
    • The src subdirectory is used to store source code. Each package is saved in a subdirectory relative to $GOPATH/src that is the package import path
    • The pkg subdirectory is used to save the target files of the compiled package
    • The bin subdirectory is used to save the compiled executable program
  • GOROOT is used to specify the installation directory of Go, as well as the location of its own standard library package.
  • The GOOS environment variable is used to specify the target operating system (such as android, linux, darwin or windows)
  • The GOARCH environment variable is used to specify the type of processor, such as amd64, 386 or arm, etc.

10.7.2 Download package

focus

  • go getYou can download a single package oruse ...to downloadEach package within the entire subdirectory. The go command of the Go language toolbox calculates and downloads each package it depends on at the same time
  • go getThe command supports currently popular hosting sites GitHub, Bitbucket, and Launchpad, and can directly request code from their version control systems. go help importpathInformation can be obtained to obtain other code hosting sites, which may require specifying the exact path and protocol of a version control system, such as Git or Mercurial.
  • go getThe code obtained by the command is the real local storage warehouse, not just copying the source file, so you can still use the version management tool to compare the changes of the local code or switch to other versions.
  • go get -uwill ensure that all packages and dependent packages are up to date, then recompile and install them. If this flag parameter is not included, and if the package already exists locally, then the code will not be automatically updated.
  • go get -uIt may not be suitable for publishing programs, because local programs may require precise version dependency management for dependent packages.
  • The usual solution is to usevendorThe directory used to store dependent packagesfixed versionThe source code of the source code, the version update of the locally dependent package is also prudent and continuously controllable.
  • View the help documentation of Vendor through go help gopaththe command
    • go getgo-getParameters are included when requesting an HTML page to distinguish it from ordinary browser requests, http://gopl.io/ch1/helloworld?go-get=1and you can view the real hosting address of the code through this

10.7.3 Building packages

focus

  • go buildThe command compiles each package specified by the command-line arguments. If the package is a library, ignore the output; if the name of the package is main, the go buildlinker will be invoked to create an executable program in the current directory; the last segment of the import path is used as the name of the executable program.
  • Because each directory contains only one package, each package corresponding to an executable program, or command in Unix terminology, will be required to be placed in a separate directory. These directories are sometimes placed under a subdirectory called the cmd directory. For example, the golang.org/x/tools/cmd/godoc command used to provide Go documentation services is placed in the cmd subdirectory
  • Each package can be specified by its import path, or by a relative directory path,Relative paths must start with . or .... If no parameter is specified, the package corresponding to the current directory is specified by default.
  • go buildExample:
// OK
$ cd $GOPATH/src/gopl.io/ch1/helloworld
$ go build
----------------------------------------
// OK
$ cd anywhere
$ go build gopl.io/ch1/helloworld
----------------------------------------
// OK
$ cd $GOPATH
$ go build ./src/gopl.io/ch1/helloworld
----------------------------------------
// ERROR
$ cd $GOPATH
$ go build src/gopl.io/ch1/helloworld
Error: cannot find package "src/gopl.io/ch1/helloworld".
----------------------------------------
// OK
$ go build quoteargs.go
  • go runCommands are actually two steps that combine build and run, which is useful for one-off programs. go runIn the parameter list on the first line of , the first one that does not .goend will be run as the parameter of the executable program.
  • go buildcommand builds the specified package and the packages it depends on, then discards all but the final executable.
  • go installThe command is similar to go buildthe command , but it saves the compilation results of each package instead of discarding them all. The compiled package will be saved to $GOPATH/pkgthe directory, the directory path corresponds to the src directory path, and the executable program will be saved to $GOPATH/binthe directory.
  • go installNeither the command nor go buildthe command will recompile packages that have not changed, which can make subsequent builds faster. In order to facilitate the compilation of dependent packages, go build -ithe command will install the packages that each target depends on.
  • Because the compilation corresponds to different operating system platforms and CPU architectures, go installthe command will install the compilation results GOOSto GOARCHthe corresponding directory. For example, on a Mac system, golang.org/x/net/htmlthe package will be installed into $GOPATH/pkg/darwin_amd64a directory of golang.org/x/net/html.afiles.
  • You only need to set the target corresponding to GOOSand GOARCH, you can cross-build for different operating systems or CPUs. runtime.GOOS, runtime.GOARCHyou can print the corresponding operating system and CPU.

10.7.4 Package documentation

focus

  • Go's coding style encourages good documentation for each package. Each exported member and package declaration in a package should be preceded by a comment stating its purpose and usage.
  • The first line of each package source file is a summary description of the package, followed by only the package declaration statement.
  • If the comment is followed by only the package declaration statement, then the comment corresponds to the documentation for the entire package. There can only be one comment corresponding to the package documentation (Annotation: In fact, there can be more than one, and they will be combined into a package documentation comment), and package comments can appear in any source file. If the comment content of the package is relatively long, it will generally be placed in an independent source file; the fmtpackage comment has as many as 300 lines. This source file dedicated to saving package documentation is usually called doc.go.
  • Parameters or other identifiers of functions in comments do not require additional quotes or other notation
// Fprintf formats according to a format specifier and writes to >w.
// It returns the number of bytes written and any write error >encountered.
func Fprintf(w io.Writer, format string, a ...interface{}) (int, >error)
  • go doccommand, which prints the package declaration and documentation comments for each member, this command does not require entering the full package import path or the correct capitalization
// 获取整个包的文档:
$ go doc time
// 获取某个具体包成员的注释文档
$ go doc time.Since
// 某个具体包的一个方法的注释文档
$ go doc time.Duration.Seconds
// 获取encoding/json包的 (*json.Decoder).Decode 方法的文档
$ go doc json.decode
  • The second tool, by the same name godoc, provides HTML pages that can be cross-referenced to each other, but contain the same and more information go docas commands . Godoc's online service contains search tools for thousands of open source packages. It is also possible to run the godoc service locally. The -analysis=typeand -analysis=pointercommand-line flags are used to open documentation and code about static analysis results.
$ godoc -http :8000
// 通过http://localhost:8000/pkg进行查看

10.7.5 Internal Packages

focus

  • Internal package, an internal package can only be imported by packages that have the same parent directory as the internal directory. For example, the net/http/internal/chunked internal package can only be imported by the net/http/httputil or net/http packages, but not by the net/url package. However, the net/url package can import the net/http/httputil package.

10.7.6 Query Packets

focus

  • go listcommand to query information about available packages.
  • Test if the package is in the workspace and print its import path
$ go list github.com/go-sql-driver/mysql
github.com/go-sql-driver/mysql
  • go listThe parameters of the command can also be used "..."to match the import path of any package,
    • This can be used to list all packages in the workspace go list ...,
    • Or all packages in the specified directory go list gopl.io/ch3/...,
    • all related to a topicgo list ...xml...
  • go listThe command can also obtain the complete meta information of each package. -jsonThe command line parameter indicates to print the meta information of each package in JSON format, for example:
$ go list -json hash
{
"Dir": "/home/gopher/go/src/hash",
"ImportPath": "hash",
"Name": "hash",
"Doc": "Package hash provides interfaces for hash functions.",
"Target": "/home/gopher/go/pkg/darwin_amd64/hash.a",
"Goroot": true,
"Standard": true,
"Root": "/home/gopher/go",
"GoFiles": [
"hash.go"
],
"Imports": [
"io"
],
"Deps": [
"errors",
"io",
"runtime",
"sync",
"sync/atomic",
"unsafe"
]
}
  • Command-line -farguments allow the user to use text/template包(§4.6)the template language to define the format of the output text.
$ go list -f '{
    
    {join .Deps " "}}' strconv
errors math runtime unicode/utf8 unsafe
-----------------------------------------
$ go list -f '{
    
    {.ImportPath}} -> {
    
    {join .Imports " "}}' >compress/...
compress/bzip2 -> bufio io sort
compress/flate -> bufio fmt io math sort strconv
compress/gzip -> bufio compress/flate errors fmt hash hash/crc32
  • go listCommands are very helpful for one-off interactive queries or automated build or test scripts, you can use go help listthe command to view the fields and meanings that can be set

Guess you like

Origin blog.csdn.net/rabbit0206/article/details/103758544