GoLang will be used in the upcoming project. I don’t know when TO Go, but I will learn Go by myself first. The learning path is based on this:
The first step is to look at the tutorial in the official documentation.
1. Install
simple
2. Go. Mod file
Note: The first and most important thing to know is that in go, a module is a collection of packages. Module is a larger concept, package is a smaller conceptCopy the code
When it comes to importing the package of some other modules, Go keeps track of those dependencies through its own module. This module, defined by go.mod, tracks other modules that provide packages. It can be said that the purpose of go.mod is to track dependencies.
2.1 Create the go.mod file to enable dependency tracking
Go. Mod uses the goModule feature, a tool for managing packages that go only released in 1.11. Prior to this were various vendoring tools for the community. Run the following command to create it:
Go mod init <module_path> or go mod initCopy the code
- This command creates a new go.mod file in the current directory, actually creating a main Module in the current folder. Do not have another go.mod file in the current directory. This makes the current directory the root directory of the goModule. This is analogous to changing the current directory to git root after git init.
- The module_path parameter can be added or not
2.1.1 Adding the module_PATH parameter
2.1.1.1 What is module_PATH
Module_path is an alias used to identify a module. The first line of the go.mod file is module_path, which represents the path and name of the current module (main module). Module_path is used to identify modules and as a prefix for finding packages within the module. Module_path can be used in several ways:
- Module_path in the first line of go.mod:
- This module_path is used to identify the name of the current module, which is also the path.
- Just create a go.mod file with init in the root directory. You don’t need to init any other modules in the subdirectory. Go automatically prefixes module_path with the relative path of the subdirectory.
- Introduce other modules using module_path:
- Module_path typically consists of a repository root path + subdirectory + Major version suffix.
- The root of the repository is the root of the VSC where the Module was developed. Many modules are placed directly in the root directory. In this case, the root directory is actually module_path, which is also the name of the module. Such as
github.com/oyishyi/my-go-project
It’s a name calledgithub.com/oyishyi/my-go-project
The root directory of the main Module of
2.1.1.2 Must XXx.com be included in the MODULE_PATH
If you’re going to publish it, you need to prefix it with this, you can’t publish it, you just can’t publish it. The official documentation for Go uses example.com, which is not published anyway, just the name of a local module. If it is published, the name should have the real domain name because you want to find the address of the Module.
2.1.2 Not adding the module_PATH parameter
If the module_path parameter is not added. Go will try to extract the import comments from the.go file, the vendoring Tool configuration file, and the current folder (if it is currently under the GOPATH path). GOPATH is an environment variable of go, referring to the absolute path of the current project’s working directory) to infer module_path. (Note: if you infer from the Vendoring Tool configuration file. There are likely to be version conflicts. That’s why Go invented the Go Module to replace other vendoring tools.)
If it’s still confusing, you can watch ithere
3. Hello, world
“Hello, world” is banned from the Nuggets.
// Declare a package called main. Package is used to package functions and consists of all files in the same directory.
package main
// Import the famous FMT package. Explanation: The FMT package contains various useful functions such as formatting text, printing, etc.
// This package belongs to the standard library and was installed when you installed GO
import "fmt"
The main function is run when the main package is running.
func main(a) {
fmt.Println("Hello, World!!!!!!!!!")}Copy the code
Run with go run
4. Find and use third-party packages
4.1 looking for
Just like the JS NPM community, the Python PIP community. Go, of course, has its own community of third-party packages. IO /quote: rsc. IO /quote: rsc. IO /quote
- Go to pkg.go.dev to search for the package you want. (You can see that packages start with domain names, which is the same suffix as the previous module_path + package suffix.)
- When you go to the package page, there is an Index in Documentation that lists all the available functions.
- When you enter the package page, you can see that the package name does not have a domain name prefix, because the package name does not have a domain name prefix, but is prefixed by module_PATH. The reason you see the prefix when searching is because you see the module_path + package suffix.
- You can see the Module information at the top of the page. Take the two packages as examples, as shown below:
As mentioned earlier, package is in module, and we use the functions in package.
4.2 the use of
- Import the package to use in your code and use the functions that come with it. The IDE will report an error saying that the package cannot be found in the existing Module.
- use
go mod tidy
Go will automatically find the module that you want to import into the package, download the latest version, and then modify the go.mod file. A go.sum file is also generated to check whether the package is complete. (By default, Tidy will use the module name when looking for packages on the Internet.) But you can use local packages by using replace to redirect to local.) - use
go run .
Run the code
5. Create your own Module
5.1 Write your own Module
The GO code makes up packages, which makes up modules. Module declares the dependencies needed to run the code. This includes versions of Go, as well as other modules for require. The go.mod file keeps track of these dependencies and is gradually updated and extended as the code is written.
go mod init go-goudoubuyong.com/greetings
Create a go.mod file.- Write some code:
package greetings import "fmt" // The Hello function: give someone a question mark func Hello(name string) string { msg := fmt.Sprintf("Hi, % V, I think you have a problem.", name) return msg } Copy the code
The above code does this:
- Declare a package, greetings, to hold related functions.
- Write a Hello function that takes a parameter named name and is of type string. This function returns a string. If you want to use functions of this package in other packages, the function names must begin with a capital letter. (If you do not capitalize the first letter, access will fail. Functions that do not capitalize are called unexported names, which is not a specification, but a syntax.)
- We use := to declare the variable and initialize the value. If you change it to equal, you declare the variable first.
var msg string msg = fmt.Aprintf("Hi, % V, I think you have a problem.", name) Copy the code
- The Sprintf function in the FMT package that outputs formatted text. %v indicates the default output format for the corresponding variable.
5.2 Using the Newly created Module
5.2.1 Directory Structure
Create another folder, init it, add the folder you created in the previous step, and the whole structure looks like thisBoth modules have a go.mod file in each.
5.2.2 Importing and Using the Package
Create a hello.go file in the new directory and write the following code:
package main
import (
"fmt"
"go-goudoubuyong.com/greetings"
)
func main(a) {
msg := greetings.Hello("zouli")
fmt.Println(msg)
}
Copy the code
This is not enough because the go.mod file does not yet contain the require package. Now it won’t work to use Go Mod Tidy, because Tidy will only look for the package online, and in our example we just gave it a false path.
5.2.3 go.mod require local package
The Go Module is created for production, so importing a local module is written in a special way. In a Production environment, packages are usually uploaded to a Repository, and Go can directly log into the Repository to download packages. The local module can’t be found without uploading, so use the replace keyword to enable go.mod to find the local module.
The idea behind this is redirection. Replace the false path to our module name with the local path. Yes, you read that right, there is no direct means to access local packages. You can only write a false path and then redirect to the local pathCopy the code
- The command to add replace is as follows, using
go mod edit
:# official document here too many =, really garbage document $ go mod edit -replace go-goudoubuyong.com/greetings=.. /greetingsCopy the code
- After running the above command, you can see that the go.mod file has changed. Of course, you can also change it directly in go.mod.
- The redirect is now complete and ready to run
go mod tidy
Tidy encounters a redirect and no longer looks for Module online. The results are as follows:The following string of numbers is a fake version number that go automatically generates, because you must have one, or if you don’t have one, you generate a fake version number.
5.3 Error Handling
- Modify the greetings.go code as follows:
package greetings import ( "errors" "fmt" ) // The Hello function: give someone a question mark // Return two values, sting and error func Hello(name string) (string, error) { if name == "" { return "", errors.New("empty name") } msg := fmt.Sprintf("Hi, % V, I think you have a problem.", name) // Since two values must be returned, here the second value is set to nil return msg, nil } Copy the code
Functions in Go can return multiple values, just note that the type of return value must be declared at the beginning.
Nil is a little bit more complicated, so look it up. Nil is a zero/null value of many types, except booleans, numeric values, and strings. Nil means no errors. - To change the folder, change the hello.go code as follows:
package main import ( "fmt" "log" "go-goudoubuyong.com/greetings" ) func main(a) { // Set the prefix of the log print, so that we know where the problem comes from log.SetPrefix("greetings: ") // Set flag to 0 so that log does not print time, source files, line numbers, etc log.SetFlags(0) // The Hello function returns an error because the argument is an empty string msg, err := greetings.Hello("") iferr ! =nil { // Fatal prints an error and exits the program // Print + os.exit (1) log.Fatal(err) } else { fmt.Println(msg) } } Copy the code
5.4 Random and init functions
There is a type called slice in GO, similar to array, that is mutable. The official documentation says this is one of the most useful types of go, but I haven’t seen it yet. Change’t. Go:
package greetings
import (
"errors"
"fmt"
"math/rand"
"time"
)
// The Hello function: give someone a question mark
func Hello(name string) (string, error) {
if name == "" {
return "", errors.New("empty name")}// Use custom functions
msg := fmt.Sprintf(randomForamt(), name)
return msg, nil
}
The init function is a special function
// Go automatically runs init at the start of the program, after the global variable is initialized
func init(a) {
// Use the current time as a random seed
rand.Seed(time.Now().UnixNano())
}
// The first letter is lowercase because it is not used externally
func randomForamt(a) string {
// Slice with string formats
// Slice hides the length in parentheses before string,
// This tells GO that the length of the array hidden behind slice can be changed
formats := []string{
"Hi, %v, Welcome!"."Great to see you, %v!"."Hail, %v, Well met!".// Add a comma to the last one
}
// Intn(k) returns an integer [1,k)
return formats[rand.Intn(len(formats))]
}
Copy the code
Key points:
- The init function.
- Slice is actually a mutable array.
- Intn function
- Len () returns the length
5.5 Multi-value input, output, loop
** Golang does not support function overloading. 支那Copy the code
In the Production environment, change the signature of a function if the function was released in the previous version. So this is not a good time to change the function. Otherwise, some of the user’s existing code will break. Therefore, it is best to create a new function. Now you want to change the Hello function to support multi-valued input and output, which will change the function signature, so create a new function Hellos.
// Return a map (key values for each name and the corresponding greeting MSG) and error
func Hellos(names []string) (map[string]string, error) {
// Generate a map
msgs := make(map[string]string)
// Iterate over the names slice and generate the greeting MSG using the old Hello function
for _, name := range names {
msg, err := Hello(name)
iferr ! =nil {
// where nil means error, MSGS should naturally be empty
return nil, err
}
msgs[name] = msg
}
return msgs, nil
}
Copy the code
Key points:
- A map is a key-value pair
make(map[key-type]value-type)
Initialize a map. - Range returns index and item for each round of the loop. use
_
To not use index. - Here,
! = nil
Common, in fact, in many other languages this paragraph is generally omitted, see the code comparison between different languages// go iferr ! =nil { // do sth } Copy the code
# python if err: # do sth Copy the code
// javascript if (err) { // do sth; } Copy the code
Then change hello.go to the following statement
names := []string{"zouli"."zl"."shabi"}
msgs, err := greetings.Hellos(names)
Copy the code
Key points:
- Initialize the syntax for slice
5.6 test
Go comes with unit tests.Copy the code
5.6.1 Creating test files
Create a new greeting_test.go file in the greeting folder. “Go test” is not recognized. “go test” is not recognized.
package greetings
import (
"regexp"
"testing"
)
// Test functions have special structures and are identified as Test functions if their names begin with Test
// The argument is fixed, which is the following argument, a pointer type of type testing.t
// Methods using this parameter t can get various logs and reports about test results
func TestHelloName(t *testing.T) {
name := "zouli"
want := regexp.MustCompile(`\b` + name + `\b`)
// Same package, even if different files do not need to import Hello
msg, err := Hello("zouli")
if! want.MatchString(msg) || err ! =nil {
t.Fatalf(`Hello("zouli") = %q, %v, want match for %#q, nil`, msg, err, want)
}
}
func TestHelloEmpty(t *testing.T) {
msg, err := Hello("")
ifmsg ! ="" || err == nil {
t.Fatalf(`Hello("") = %q, %v, want "", error`, msg, err)
}
}
Copy the code
5.6.2 usego test
To begin testing
- Use it directly in the directory
go test
You can start the test, or usego test -v
View the detailed output.go test
Will automatically find the current directory_test
Go file at the end. And run itTest
Function at the beginning.
5.7 Compiling and Installing Applications
This section describes two methods, Go Build and Go Install. The former compiles packages, but does not install them; The latter is compiled and installed.
- Use it in the Hello folder
go build
, which compiles to an executable binary. Execute the binary file to run. - You need to go to the directory where the binary file resides to run it. If you want to run anywhere, you need to install the package.
- use
go list -f "{{.Target}}"
You can see where you want to install. You can also see the package installation location of GO. - Set this location to an environment variable to use installed packages anywhere.
$ser PATH=%PATH%; C:\path\to\your\install\directoryCopy the code
- Or if you want to install the package somewhere else, you can change the go environment variable
GOBIN
.$ go env -w GOBIN=C:\path\to\your\bin Copy the code
- You can then run the package by packaging the name directly on the terminal