Hi, I’m Mingo.

In their learning Golang this time, I wrote a detailed study notes on my personal number WeChat public Go programming time, for the language, I was a beginner, so writing should fit in with the new to classmates, if you are just learning the language, don’t focus on prevention, study together, Grow together.

My Github:github.com/iswbm/GolangCodingTime my online blog: golang.iswbm.com


1. Single-line import and multi-line import

In the Go language, a package can contain more than one.go file (which must be in the same level of folder), as long as the.go file headers all declare the same package using the package keyword.

There are two ways to import packages:

  • A single import
import "fmt"
import "sync" Copy the code
  • Multi-line import
import(
    "fmt"
    "sync"
)Copy the code

As you can see, packages imported in Go must be enclosed in double quotes, just to make fun of it here.

2. Use an alias

In some scenarios, we may need to rename the imported package, for example

  • There was a conflict when we imported two packages with the same package name, and here we define an alias for one of the packages
Import ("crypto/rand" mrand "math/rand" // replace name with mrand to avoid collisions)Copy the code
  • We imported a package with a long name. To avoid having to write such a long package name, we can define the alias like this
import hw "helloworldtestmodule"Copy the code
  • Prevent imported package names from conflicting with local variables, such as path, which is a very common variable name, and imported standard packages.
import pathpkg "path"Copy the code

3. Perform point-to-point operations

For example, if you use a tool kit like FMT frequently inside our program, then every time you print using its print function, the package name + method name.

For this kind of high frequency package, we can define it as “own” when importing (the method is to use a.), and its method is our method.

Since then, we don’t need to add FMT to print anymore.

import . "fmt"

func main() {
    Println("hello, world")
}Copy the code

There is a danger, however, that the imported package may contain functions that conflict with our own functions.

4. Initialize the package

Each package is allowed to have an init function, and when the package is imported, the init function of the package is executed to do some initialization tasks.

There are two things to note about executing the init function

  1. The init function takes precedence over the main function

  2. In a package reference chain, package initialization is depth-first. For example, if there is A package reference relationship: main→A→B→C, then the initialization order is

    C.i nit - B.i nit - Anderson, nit - mainCopy the code

5. Anonymous import of packages

When we import a package, if the package is not used, we will report an error at compile time.

But what about cases where we import a package and just want to execute the init function in the package to do some initialization?

Anonymous imports can be used as follows, where the underscore is a blank identifier and cannot be accessed

Decoder import _ "image/ PNG"Copy the code

Since the init function is executed at import time, the package is still compiled into the executable at compile time.

6. Import a path or a package?

When we import TestModule /foo using import, beginners often ask, is foo a package or is it just the name of the directory in which the package resides?

import "testmodule/foo"Copy the code

To arrive at this conclusion, an experiment was conducted (see the code example in “Number 7”) and the result was:

  • The import mode is based on the directory. After you import a directory, you can use all the packages in that directory.
  • As a matter of habit, the package name and directory name are usually set the same, giving you the illusion that you are importing a package.

7. Relative and absolute imports

As far as I know, relative imports are not supported before Go 1.10, but after Go 1.10.

Absolute import: Search for packages from $GOPATH/ SRC or $GOROOT or $GOPATH/ PKG /mod and import

Relative import: Searches for packages from the current directory and starts importing. It looks like this

import ( "./module1" ".. /module2" ".. /.. /module3" ".. /module4/module5" )Copy the code

Let me give you an example

Use absolute imports

There is a directory structure like this (make sure the current directory is under GOPATH)

Where main.go looks like this

Package main import ("app/utilset" // absolute path import is used) func main() {utils.printhello ()}Copy the code

In the same directory as main.go, there is another folder, utilset. To get to the point where “import imports a path, not a package,” I define a hello.go file in the utilset directory that defines the package utils.

Package utils import "FMT" func PrintHello(){fmt.println ("Hello, I'm in utilset utils ")}Copy the code

The result is as follows

Use relative imports

Once again, change the absolute import to the relative import

Set the GOPATH path back (compare GOPATH with absolute path above)

And then run it again

To summarize, there are two things to note when using relative imports

  • Do not place the project under $GOPATH/ SRC, otherwise it will give an error (for example, if I change the current project directory to GOPATH, it will give an error)

  • Go Modules don’t support relative imports, and you can’t use relative imports after you enable GO111MODULE.

Finally, it has to be said that the readability of the project is compromised by using the relative import approach, without using the developer to sort out the entire reference relationship.

Therefore, absolute references are generally recommended. With absolute references, there’s priority again

8. Priority of the package import path

In the previous section, we introduced three different package dependency management schemes. Different management modes may lead to different paths for storing packages. Some packages can be placed under GOPATH, some packages can be placed under Vendor, and some packages can be placed under GOROOT as built-in packages.

So the question is, if there is a package with the same name but different version under these three different paths, which package should we import?

So we need to figure out, what is the priority of the package search path in Golang?

At this point, you need to distinguish which mode is used for package management.

If you use Govendor

When we import a package, it will:

  1. First from the project root directoryvendorSearch in directory
  2. Finally from the$GOROOT/srcLook in directory
  3. Then from$GOPATH/srcLook in directory
  4. If none are found, report an error.

In order to verify this process, I created a vendor directory during the creation, and then turned on the vendor mode. I randomly imported a package PKG in main.go. Since THIS package was randomly designated by me, of course, it could not be found. Golang prints the process of the search in the error message, and from this message, you can see Golang’s packet lookup priority.

If you use go modules

$GOPATH/ PKG /mod = $GOPATH/ PKG /mod = $GOPATH/ PKG /mod

If you import a package that doesn’t have a domain name (such as “FMT”), you’ll just look it up in $GOROOT.

It is also important to note that when your project has a vendor directory, you will only look in the vendor directory, regardless of whether your package has a domain name or not.

Usually the vendor directory is generated by the go mod vendor command, which packages all project dependencies into the Verdor folder in your project directory.

read

  • How do I import local packages using the Go Module

A series of reading

01. Setup of development environment (Goland & VS Code)

02. Learn five ways to create variables

03. Data type: **Integer and floating point **

Data types: byte, RUNe, and String

05. Data types: Array and slice

06. Data types: dictionary and Boolean

07. Data type: pointer

08. Object-oriented Programming: Structures and Inheritance

09. An article to understand the function in Go

10. Go language flow control: if-else conditional statements

11. Go language flow control: switch-case selection statement

12. Go language flow control: for loop statement

13. Go language flow control: GOto unconditional jump

14. Go language flow control: defer the call

15. Object-oriented programming: Interfaces and polymorphism

Key words: make and new difference?

17. An article to understand the blocks and scopes in Go

18. Learn Go coroutine: Goroutine

19. Learn Go coroutines: Detail channels/channels

20. Several classic error cases of channel deadlock

21. Learn the Go coroutine: WaitGroup

22. Learn Go coroutines: mutex and read-write locks

23. Exception handling in Go: Panic and recover

24. Super detailed interpretation of Go Modules past life and the introduction to use

25. Go language about package import must learn 8 knowledge points

26. How to open source your modules for others to use?

27. What about type assertions in Go?

28. These five points will help you understand the select usage of Go