A, Go source file

Go source file:

As shown in the figure above, it is divided into three categories:

1, command source file:

A main function that declares itself a part of the main code package and contains no argument declarations and result declarations.

After the command source files are installed, if GOPATH has only one workspace, the corresponding executable files will be stored in the bin folder of the current workspace. If you have more than one workspace, it will be installed in the directory pointed to by GOBIN.

The command source file is the entry to the Go program.

It is best not to put multiple command source files in the same code package. Multiple command source files can be run separately, but not through Go build and Go install.

Go: helloWorld2.go: helloWorld2.go: HelloWorld2.go: HelloWorld2.go

package mainimport "fmt"func main(){    fmt.Println("I'm the second HelloWorld file")    fmt.Print("Go Go Go !!!")}Copy the code

There are two go files in the hello directory, one is helloWorld. go, the other is helloWorld2.go. To clarify, there are two command source files in the above folder, and both declare themselves to be part of the main package.

Open the terminal, go to the directory Hello, you can also see these two files:

localhost:~ ruby cd go/src/hellolocalhost:hello ruby lshelloworld.go   helloworld2.goCopy the code

Then we execute the go run command separately, and we can see that both go files can be executed:

localhost:hello ruby$ go run helloworld.goHelloWorldGo Go Go !!! Localhost :hello ruby$go run helloWorld2. goCopy the code

Next run go Build and Go Install to see what happens:

localhost:hello ruby$ go build # hello./helloworld2.go:3:6: main redeclared in this block previous declaration at ./helloworld.go:3:6localhost:hello ruby$ go install# hello./helloworld2.go:3:6: main redeclared in this block previous declaration at ./helloworld.go:3:6localhost:hello ruby$Copy the code

Operation effect picture:

This proves that multiple command source files can be run separately, but not through Go Build and Go install.

The same is true of command source files and library source files, which cannot be compiled and installed using conventional methods like Go Build and Go Install. The specific example is similar to the above, so I won’t post the code here.

So the command source file should be placed in a separate code package.

2, library source file

Library source files are source files that do not have the above two characteristics of command source files. A plain source file that exists in a code package.

After the library source files are installed, the corresponding archive files (.a files) are placed in the platform-specific directory of the PKG in the current workspace.

3, test the source file

A code file whose name ends with _test.go and must contain functions prefixed with the name Test or Benchmark:

func TestXXX( t *testing.T) {​}Copy the code

A function whose name is prefixed with Test can only accept arguments to * testing.t. This Test function is a functional Test function.

func BenchmarkXXX( b *testing.B) {​}​Copy the code

A function whose name is prefixed with * testing.b can only take arguments from * testing.b. This is a performance test function.

Now the answer is obvious:

The command source file can be run separately. You can run the go run command directly, or run the go build or go install command to get the corresponding executable file. So command source files can be run in any directory on the machine.

Here’s an example:

For example, when we brush algorithm problems on LeetCode, what we write at this time is a program, which is the command source file. You can create a new GO file in any folder of the computer and start to brush problems. After writing, you can run.

The same cannot be said of code in corporate projects, which must be stored in the GOPATH directory. Because the company project can not only command source files, must contain library source files, even contain test source files.

Go command

Currently, the latest version of Go, 1.12, has the following 17 basic commands.

We can open the terminal and type: Go help to see the go commands and a brief introduction.

    bug         start a bug report    build       compile packages and dependencies    clean       remove object files and cached files    doc         show documentation for package or symbol    env         printGo environment information fix update packages to use new APIs fmt gofmt (reformat) package sources generate generate Go  files by processingsource    get         download and install packages and dependencies    install     compile and install packages and dependencies    list        list packages or modules    mod         module maintenance    run         compile and run Go program    test        test packages    tool        run specified go tool    version     print Go version    vet         report likely mistakes in packagesCopy the code

Among them, build, get, install and run are related to compilation. Let’s look at each of these in turn.

Before analyzing the four commands in detail, let’s list the common command flags that apply to each of these commands:

The name of the instructions
-a Used to force a recompilation of all involved Go code packages, including those in the Go standard library, even if they are up to date. This tag gives us a chance to do some experimentation by changing the underlying code package.
-n Causes a command to print only all the commands used in its execution, without actually executing them. If you don’t want to change anything, rather than just see or verify the execution of a command, this is a good use.
-race Used to detect and report data contention problems in specified Go language programs. This is one of the most important checks when writing concurrent programs in Go.
-v This command is used to print code packages involved in command execution. This must include the object code package that we specify, and sometimes those that the code package depends on directly or indirectly. This will let you know which packages have been executed.
-work Print the name of the temporary working directory that is generated and used during command execution and is not deleted after command execution is complete. The files in this directory may be useful to you, as well as give you a side view of the command execution process. If this flag is not added, the temporary working directory will be deleted before the command completes.
-x Causes a command to print all the commands used in its execution and to execute them simultaneously.

1. go run

This command is specifically used to run command source files, note that this command is not used to run all Go source files!

The go run command can accept only one command source file and several library source files (which must belong to the main package) as file parameters, and cannot accept test source files. It checks the type of the source file as it executes. If there are multiple or no command source files in the argument, the go run command simply prints an error message and exits, rather than continuing execution.

What exactly does this order do? To analyze this, let’s create a new file: mytest.go and add the following code:

package mainimport "fmt"func main(){    fmt.Println("HelloWorld")    fmt.Println("Hello, Go!!")}Copy the code

Run go run with -n:

localhost:hello ruby$ go run -n mytest.go ​## command-line-arguments# mkdir -p $WORK/b001/cat >$WORK/b001/importcfg << 'EOF' # internal# import configpackagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.apackagefile runtime=/usr/local/go/pkg/darwin_amd64/runtime.aEOFcd /Users/ruby/go/src/hello/usr/local/go/pkg/tool/darwin_amd64/compile -o $WORK/b001/_pkg_.a -trimpath $WORK/b001 -p main - complete - buildid ieg41NOobNF0eqq3xgnP/ieg41NOobNF0eqq3xgnP - dwarf = false - goversion go1.12.1 - D _/Users/ruby/go/src/hello -importcfg $WORK/b001/importcfg -pack -c=4 ./mytest.go/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/_pkg_.a # internalcat >$WORK/b001/importcfg.link <<  'EOF' # internal... # is omitted EOFmkdir - p $5 / b001 / exe/CD/usr/local/go/PKG/tool/darwin_amd64 / link - o $5 / b001 / exe/mytest - importcfg $WORK/b001/importcfg.link -s -w -buildmode=exe -buildid=vpgT856LhbZPXp6WeHib/ieg41NOobNF0eqq3xgnP/ieg41NOobNF0eqq3xgnP/vpgT856LhbZPXp6WeHib -extld=clang $5 / b001 _pkg_. A $5 / b001 / exe/mytestlocalhost: hello ruby $Copy the code

Operation effect picture:

Here you can see that two temporary folders b001 and exe are created, first execute compile command, then link, generate archive file. A and final executable file, the final executable file is placed in the exe folder. The last step of the command is to execute the executable.

To sum up:

For example, the generated temporary file can be seen with go run-work. For example, the generated temporary folder is in the following path:

localhost:hello ruby$ go run -work mytest.go WORK = / var/folders/kt/nlhsnpgn6lgd_q16f8j83sbh0000gn/T/go - build593750496HelloWorld hello, go!!!!!! localhost:hello ruby$Copy the code

We enter: / var/folders/kt/nlhsnpgn6lgd_q16f8j83sbh0000gn/T/go – build593750496 directory, you can see the following directory structure:

As you can see, the final result of the Go run command is two files, an archive and an executable.

The go run command does not compile the imported package again if it is not changed the second time it is executed. Static links directly in.

localhost:hello ruby$ go run -n mytest.go mkdir -p $WORK/b001/cat >$WORK/b001/importcfg.link << 'EOF' # internalpackagefile command-line-arguments=/Users/ruby/Library/Caches/go-build/6b/6b9577027c8da20b0ae6da790267f558b3b71eea1feb44039fb933b35e aef6f9-dpackagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.a... EOFmkdir -p $WORK/b001/exe/cd ./usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/mytest -importcfg $WORK/b001/importcfg.link -s -w -buildmode=exe -buildid=goiqf_1cemqljgOYzSRA/ieg41NOobNF0eqq3xgnP/MVbHdxOky1BGK6Aq_4bM/goiqf_1cemqljgOYzSRA -extld=clang /Users/ruby/Library/Caches/go-build/6b/6b9577027c8da20b0ae6da790267f558b3b71eea1feb44039fb933b35eaef6f9-d$WORK/b001/exe/ Mytestlocalhost: hello ruby $Copy the code

2. go build

The go build command is primarily used to test build. During the compilation of a package, packages associated with it are compiled at the same time, if necessary.

  1. For a normal package, when you run the go build command, no files are generated.

  2. In the case of the main package, an executable file is generated in the current directory after only the go build command is executed. To generate an EXE file in the $GOPATH/bin directory, run go Install or use the Go build -o directory/executable file.

  3. If there are multiple files in a folder and you want to build only one of them, you can add the file name after go build, for example, go build a.Go; The go build command compiles all go files in the current directory by default.

  4. You can also specify the file name of the compiled output. For example, we can specify the go build-o executable file name, which by default is the name of your package (not the main package) or the name of the first source file (the main package).

  5. Go Build ignores directories with “_” or “. Go file at the beginning.

  6. If your source code needs to be treated differently for different operating systems, you can name your files with different operating system suffixes.

If there is only one command source file in the code package, run the go build command to generate an executable file with the same name as the directory.

// Assume that the current folder is called Hellolocalhost: Hello Ruby $pwd/Users/ruby/go/src/hellolocalhost:hello ruby$ lshelloworld.golocalhost:hello ruby$ go buildlocalhost:hello ruby$ lshello  helloworld.golocalhost:hello ruby$Copy the code

An executable file named executable (Unix Executable on Mac or EXE on Windows) is generated in the current directory

However, in this case, if you use the go install command, if there is only one workspace in GOPATH, the corresponding executable will be generated in the bin directory of the current workspace. If there are multiple workspaces under GOPATH, the corresponding executable files are generated under GOBIN.

localhost:hello ruby$ go installgo install hello: open /usr/local/go/bin/hello: permission deniedlocalhost:hello ruby$ Copy the code

The problem is that it needs to create a bin directory and put the executable file in it. Currently, we do not have a bin directory under Gopath, so we need to create this file first. Ordinary users do not have permission to create folders directly, which has nothing to do with the Go command. We can execute this command by adding sodu, which means to execute as administrator, and enter the password to create the bin folder.

Execute again:

localhost:hello ruby$ sudo go installPassword:localhost:hello ruby$ ​Copy the code

The executable file is missing after executing Go Install! Where did it go? It is actually moved to the bin directory (GOBIN if you have multiple workspaces under GOPATH).

View the directory:

So what do Go Build and Go Install do?

Let’s start with Go Build. Go Build is used to compile the source files or code packages we specify and their dependencies. Note, however, that when used to compile non-command source files, i.e. library source files, go Build does not produce any results. In this case, the go build command only checks the validity of the library source files, and only does a checking compile without printing any result files.

Go Build compiles the command source file to generate an executable file in the command’s execution directory, as demonstrated in the example above.

Without appending a directory path to go Build, it compiles the current directory as a code package. If the package import path is followed by the go build command, the package and its dependencies will be compiled.

What does the go build command actually do? We can run the -n command to see:

localhost:hello ruby$ go build -n​## hello# mkdir -p $WORK/b001/cat >$WORK/b001/importcfg << 'EOF' # internal# import configpackagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.apackagefile runtime=/usr/local/go/pkg/darwin_amd64/runtime.aEOFcd /Users/ruby/go/src/hello/usr/local/go/pkg/tool/darwin_amd64/compile -o $WORK/b001/_pkg_.a -trimpath $WORK/b001 -p main - complete - buildid PXDetO1R1NhLFMK5QGUc/PXDetO1R1NhLFMK5QGUc - goversion go1.12.1 - D "" - importcfg $5 / b001 / importcfg -pack -c=4 ./helloworld.go/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/_pkg_.a # internalcat >$WORK/b001/importcfg.link << 'EOF' # internalpackagefile hello=$WORK/b001/_pkg_.a... EOFmkdir -p $WORK/b001/exe/cd ./usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -buildmode=exe -buildid=diTh1q6kcbGRIX3aj3mU/PXDetO1R1NhLFMK5QGUc/PXDetO1R1NhLFMK5QGUc/diTh1q6kcbGRIX3aj3mU -extld=clang $WORK/b001/_pkg_.a/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/exe/a.out # internalmv $WORK/b001/exe/a.out Hellolocalhost: hello ruby $Copy the code

As you can see, the execution process is basically the same as go Run, except that in the last step, Go Run executes the executable, but the go build command simply compiles the library source file and moves the executable to a folder in the current directory.

To sum up:

3. go install

The go install command is used to compile and install code packages or source files.

The go install command is actually a two-step operation internally: the first step is to generate the result file (executable or.a package), and the second step moves the compiled result to $GOPATH/ PKG or $GOPATH/bin.

Executable files: generally, go install is generated by the go file with the main function, there is a function entry, all can be directly run.

A Application package: Generally, go install is generated by the Go file that does not contain the main function. There is no function entry and can only be called.

Go Install is used to compile and install specified code packages and their dependencies. This command handles dependencies for the specified code package if they have not been compiled and installed. As with the Go build command, the package parameters passed to the Go Install command should be provided as an import path. In fact, the go install command does only one more thing than the Go Build command does: install the compiled result file into the specified directory.

The installation code package generates archive files (that is,.a files) in the platform-specific directory of the PKG in the current workspace. The installation command source file generates an executable file in the bin directory of the current workspace (or GOBIN if there are multiple workspaces under GOPATH).

Similarly, the go install command will install the current directory as a code package if no parameters are appended. This is exactly the same as the go build command.

If the go install command is followed by the package import path as an argument, the package and its dependencies will be installed.

If the go install command is followed by the command source file and the related library source file, only these files will be compiled and installed.

What does the go install command actually do?

localhost:hello ruby$ go install -n​## hello# mkdir -p $WORK/b001/cat >$WORK/b001/importcfg << 'EOF' # internal# import configpackagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.apackagefile runtime=/usr/local/go/pkg/darwin_amd64/runtime.aEOFcd /Users/ruby/go/src/hello/usr/local/go/pkg/tool/darwin_amd64/compile -o $WORK/b001/_pkg_.a -trimpath $WORK/b001 -p main - complete-buildid E1CTs4eXkD5M28s_FQXT/E1CTs4eXkD5M28s_FQXT -goversion go1.12.1 -d "" -importcfg $WORK/b001/importcfg -pack -c=4 ./helloworld.go/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/_pkg_.a # internalcat >$WORK/b001/importcfg.link << 'EOF' # internalpackagefile hello=$WORK/b001/_pkg_.apackagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.a... EOFmkdir -p $WORK/b001/exe/cd ./usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -buildmode=exe -buildid=FJ6kJTmN9rcWcwLhqfiQ/E1CTs4eXkD5M28s_FQXT/E1CTs4eXkD5M28s_FQXT/FJ6kJTmN9rcWcwLhqfiQ -extld=clang $WORK/b001/_pkg_.a/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/exe/a.out # internalmkdir -p / usr/local/go/bin / $5 / mv b001 / exe/a.out/usr/local/go/bin/hellolocalhost: hello ruby $Copy the code

The previous steps are the same as Go Run and Go Build, except for the last step. Go Install will install the command source files in the bin directory of the current workspace (or GOBIN if there are multiple workspaces under GOPATH). If it is a library source file, it will be installed in the platform-specific directory of the PKG in the current workspace.

To sum up:

When installing multiple library source files, you may encounter the following problems:

localhost:hello ruby$  go install envir.go fpath.go ipath.go pnode.go util.gogo install: no install location for .go files listed on command line (GOBIN not set)Copy the code

Furthermore, the error message will still appear after we set the correct value for the environment variable GOBIN. This is because only when the command source file is installed will the command program use the value of the environment variable GOBIN as the directory where the resulting file is stored. When you install a library source file, the variable inside the command program that represents the directory where the result file is stored is not assigned. Finally, the command program will find that it is still an invalid null value. Therefore, the command program will also return an error about “no installation location”. This leads us to the conclusion that we can only install library source files by installing code packages, not by listing and installing them in the go install command. In addition, the go install command currently does not accept the -o tag to customize the location of the result file. This also shows that the go install command does not support installation operations against library source files.

4. go get

The go get command is used to download and install code packages from a remote code repository such as Github. Note that the go get command downloads the current code package to the SRC directory in the first workspace in $GOPATH and installs it.

When using Go Get to download a third-party package, it will still be downloaded to the first workspace of $GOPATH instead of the vendor directory. There is no real package dependency management in the current work chain, but fortunately there are a number of third-party tools available.

If the -d flag is added to the Go Get download, the download will only perform the download, not the install. For example, some very special code packages need special handling during installation, so we need to download them first, so we use the -d flag.

Another useful tag is the -U tag, plus it can leverage the network to update existing code packages and their dependencies. If you have already downloaded a package and the package has been updated, you can use the -u flag to update the corresponding package locally. If you do not add the -u flag and execute go get an existing package, you will find that the command does nothing. With the -u tag, git pull will be executed to pull the latest version of the latest package, download it, and install it.

The go get command also has a commendable feature called smart download. After using it to check out or update the code package, it looks for tags or branches that correspond to the version number of the locally installed Go language. For example, if the natively installed version of the Go language is 1.x, the Go get command looks for a label or branch named “go1” in the remote repository of that code package. If the specified label or branch is found, the version of the native code package is switched to that label or branch. If the specified label or branch is not found, the version of the native code package is switched to the latest version of the trunk.

Some commonly used tags for go Get are as follows:

Tag name describes
-d Have the command program perform only the download action, not the install action.
-f Only in the use of-uValid only when marked. This flag causes the command to ignore checking the import path of the downloaded code package. This is especially important if the package you download and install belongs to a project that you Fork from someone else.
-fix Have the command program perform corrective actions after downloading the code package before compiling and installing it.
-insecure Allows a command program to download a specified code package using an insecure scheme such as HTTP. You can add this flag if you are using a code repository that does not have HTTPS support, such as an in-house Gitlab. Please use it only when you are sure it is safe.
-t Causes the command program to simultaneously download and install the dependencies in the test source file in the specified code package.
-u Let commands leverage the network to update existing code packages and their dependencies. By default, this command only downloads non-local code packages from the network and does not update existing code packages.

What does the go Get command actually do? So let’s print out the execution of each step.

localhost:hello ruby$ go get -x github.com/go-errors/errorscd .git clonehttps://github.com/go-errors/errors /Users/ruby/go/src/github.com/go-errors/errorscd /Users/ruby/go/src/github.com/go-errors/errorsgit submodule update --init --recursivecd /Users/ruby/go/src/github.com/go-errors/errorsgit show-refcd /Users/ruby/go/src/github.com/go-errors/errorsgit submodule  update --init --recursiveWORK=/var/folders/kt/nlhsnpgn6lgd_q16f8j83sbh0000gn/T/go-build188558329localhost:hello ruby$Copy the code

Effect:

After executing the go get command, the git clone method will be called to download the source code and compile it. Finally, the library source file will be compiled into an archive file and installed in the relevant platform directory corresponding to the PKG.

To sum up:

5. Other commands

go clean

The go clean command is used to remove compiled files from the current source package, including

  • _obj/ Old object directory, left over from Makefiles

  • _test/ Old test directory, left over from Makefiles

  • _testmain.go Old gotest file left over from Makefiles

  • Test. out Old test record, left behind by Makefiles

  • Build. out Old test record, left behind by Makefiles

  • *.[568ao] object file, left over from Makefiles

  • DIR(.exe) is generated by Go Build

  • Dir.test (.exe) is generated by go test -c

  • MAINFILE(.exe) is generated by go build mainfile.go

go fmt

The go FMT command is mainly used to format the code files you have written.

For example, if we write a badly formatted test.go file, we can just use the FMT go test.go command and ask GO to format our code file for us. However, we rarely use this command, because our development tools usually have automatic formatting on save, which basically calls the go FMT command.

With the go FMT command, more often gofmt is used, and the argument -w is required, otherwise the formatting result will not be written to the file. Gofmt -w SRC, can format the entire project.

go test

The go test command automatically reads a file named *_test.go in the source directory to generate and run the test executable. By default, you don’t need any arguments, it will automatically test all the test files in your source package, of course you can also add arguments, see Go Help TestFlag for details

go doc

The go doc command is a powerful documentation tool.

How do I view the documentation for the corresponding package? For example, the builtin package, go doc builtin; If it is an HTTP package, go doc net/ HTTP; To view a function in a package, go doc FMT Printf; You can also view the corresponding code by executing go doc-src FMT Printf;

Net/HTTP: ruby$go doc net/ HTTP: ruby$go doc time  ruby$ go doc fmt PrintfCopy the code

Run the go doc-http =: port number on the CLI, for example, godoc-http =:8080. Then open 127.0.0.1:8080 in your browser and you’ll see a local copy version of Golang.org that allows you to query PKG documents, among other things. If you set up GOPATH, the PKG category will list documentation not only for standard packages, but also for all projects in your local GOPATH, which is a good choice for users who are often restricted in their access.

localhost:hello ruby$ godoc -http=:9527Copy the code

The go fix is used to fix the code of the previous version to the new version, for example, the code of the previous version before GO1 is converted to GO1

Go Version View the current GO version

Go env Displays the current GO environment variables

Go List lists all current installed packages