“This is my 32nd day of participating in the First Challenge 2022. For details: First Challenge 2022”
Go learn mod
Mainly divided into the following parts to learn:
- go module ref
- All the problems you will encounter during development
- Net friend notes, this part basically is to check a leak to fill a vacancy
go module reference
The Go Module is used to manage dependencies.
The definition of the module/package/version
- Module, a series of packages that feature them shipped together, with versions
- It can be downloaded directly from the repository or module agent service
- Module is identified by Module path, which is a line in go.mod
- The root directory of module is the directory that contains go.mod
- The main mudle directory is the go command execution directory
- Package, a collection of source files in the same directory, characteristically compiled together
- The module inside the package
- Package path = Module path + (relative to the module root) subdirectory
- Module path, module path, standard name of module
- Declaration specified by module in go.mod
- Module path is the prefix of the package path for all packages in a module
- The Module path usually contains the root of a repository
- If the major version number is >=2, you also need to include the major version suffix, which is required
- Two meanings
- Versions younger than version 2 do not require a major version suffix, nor do versions 1.9.9
- Eg: the module github.com/pion/webrtc/v3 major version suffix is v3
- Two meanings
- Second, most modules are defined in the repository root, so module path and repository address can be consistent
- If module is no longer the root of the repository, the specific subdirectory is Module Path
- In this case, the specific subdirectory does not need to have the main version suffix, and whether the module path should have “v2” depends on whether the version number is 2
- If the major version number is >=2, you also need to include the major version suffix, which is required
- Conversely, if module path ends in (eg:”v2″), then v2 might be
- Major version suffix
- Subdirectories themselves contain v2 directories
- Version identifies an immutable snapshot of the Module
- It may be a release, eg: v1.2.3
- It could be a pre-release version, eg: V1.2.3 – Beta4, or v1.2.3-pre
- Version numbers begin with v, followed by “Semantic version 2.0”
- In semantic version 2.0, there are major versions. Revised version – Pre-release + Build meta information
- Build meta information is ignored during version comparisons
- Go.mod can present build meta information,+incompatible indicating that non-Module projects have major versions of 2 or above
- The go command automatically converts “tag/branch/commit “to the corresponding standard version number
- Build information is first removed (except for +incompatible)
- Prerelease information will be replaced with “commit number + timestamp”
- Pre-release version
- The writing is similar to v0.0.0-20191109021931-DAA7C04131F5
- There are 3 parts:
- VX0.0.0 or vX. Y.Z – 0; If there is no tag, it is vx.0.0
- Time stamp, year, month, day, hour, minute, second
- Commit number, the first 12 bits of Git, the commit number filled with 0 of SVN
- Vx.0.0 – YYYYMMDDHhmmss – abcdefABCDef applies when there is no base version and only X matches the major version number
- Vx.y.z-pre-0.yyyymmddhhmmss – abcDefABCDef The base version is vx.y.z-pre
- Vx.y.(Z+1)-0. yyyYMMDDHhmmss – abcDefABCDef The base version is vx.y.z
- The base version is V1.2.3, so the next pre-release is V1.2.4-0.20191109021931-DAA7C04131F5
- Multiple pre-release versions can point to the same commit, but their base version is different: this can only happen if the lower version is tagged after the pre-release
- The entire pre-release logic ensures that the pre-release version is higher than all releases, but lower than all future releases
- Pre-release versions of the same base version are compared in chronological order when compared
- The reliance on timestamps is to prevent attacks based on the production area of the pre-dispatch machine
- Pre-release versions are automatically maintained by the tool and do not need to be written manually
- Major version,eg: V3 V2
- According to the specification of semantic version 2.0, this repository contains at least two incompatible major versions
- Go.mod needs to indicate which version it refers to, and v1 without a major version number is used
- The rule for the main version number suffix is that if both the old and new packages use the same import path, the new package must be backward compatible with the old one
- That’s why you need to add v2/v3, etc., to the import path, mainly to distinguish incompatible versions
- V0 is unstable, and v1 is the most likely version to be backward compatible, so v0 and V1 are not required for major versions
- Exception: gopkg. Need to keep in the major version number, eg: gopkg. In/pion/webrtc v3
- The suffix is not /, but.
- Gopkg. in is a routing station implemented for the Github repository
- Using the major version number, you can use different major versions at the same time in a compilation
- How packages are added to modules (here’s how to parse them)
- The parse process here refers specifically to: parsing using the go command +package path
- (01) Use the package path prefix to find the package in the build list
- Build list
- Is the entire Module diagram
- Is a collection of the smallest versions of all dependent Modules
- Build list
- (02) Found the module with the Pakcage prefix in the build list
- If found, the go command further checks to see if the package exists in the Module
- Package subdirectories (if package subdirectories) exist in Module
- If any go source exists in a subdirectory
- The go Build constraint does not apply here
- If you are sure that the Module provides the package you are looking for, use this module
- If the module does not provide the package you are looking for; Or if more than one module provides the package you are looking for, the go command will report an error
- flag
-mod=mod
The go command will try to find a new module and update the corresponding go.mod/go.sum- Go get/go mod Tidy by default
-mod=mod
flag
- Go get/go mod Tidy by default
- flag
- If found, the go command further checks to see if the package exists in the Module
- (03) Find a new module for package in build list
- The first step is to confirm the proxy information (the GoProxy environment variable)
- Goproxy consists of a list of proxy urls and direct/off, separated by commas
- Proxy urls are all communicated using the GoProxy protocol
- Direct: communicates directly with the version control system (eg: Git)
- Off indicates that communication should not be attempted
- Two environment variables, goprivate/ gonoProxy, also affect the behavior here
- Goproxy consists of a list of proxy urls and direct/off, separated by commas
- The go command finds module for the agent information (if it fails, the next agent information)
- To do this, take the individual prefixes of the Package Path to the agent and request them (in parallel)
- The sign of failure is that all requests failed (404/410); Or module does not provide the specified package
- There are two signs of success:
- One is that there is a request for success
- Second, the go command will download the corresponding Module for all successful requests and find the package in the module
- If more than one request succeeds, the module with the longest path is the one to look for
- The first step is to confirm the proxy information (the GoProxy environment variable)
- (04) If the go command finds a new moudle for the package, update the require directive for the main moudle go.mod
- The rule of finding modules by package ensures that an identical package will be loaded in the future and will use the same Module as the old package
- If a parsed package is not imported directly by the main Module, add the comment // indirect
- There are two ways this can happen:
- If the go Module is not enabled for direct dependencies on A, the BCD for A dependencies will appear in the main moudle with A // indirect added
- Add A dependency on D to the main module and add A // indirect to the go Module
- When all GO projects are migrated to the Go Module, there will be no indirect dependency annotations
- Go mod why-m dependencies can find dependency chains
- Go mod why -m all can find all dependent chains
- There are two ways this can happen:
Go. The mod file
Features of the go.mod file:
- Utf-8 encoded text file
- In the root directory
- The information is stored in lines, and each line is a separate instruction (keyword + parameter)
- The same kind of instructions can be “merged like terms”
- The design goal is “machine write, human read.”
Multiple subcommands of the go command can change go.mod,eg: go get command. The command to load the Module diagram automatically updates go.mod as needed.
The main module requires a go.mod file.
Lexical element
When go.mod is parsed, it is split into tokens (tokens are symbolic tokens). Tokens can be Spaces/comments/punctuation/keywords/identifiers/strings.
Space:
- White space characters
- tab
- Carriage returns
With the exception of line breaks, other Spaces are only used to separate other tokens. Line breaks are important because go.mod is line-oriented.
Note:
// start, until line no. Any other type of comment is illegal.
Punctuation:
()=>3 punctuation marks, the others are illegal.
Key words:
Used to distinguish instruction types, a line is an instruction. Keyword contains: the module/go/require/replace/exclude/retract.
Identifier:
A string without Spaces,eg: Module path or semantic version.
String:
A string wrapped in quotes, similar to the two types of string for go, and go.mod is the same two types. One with escape (enclosed in quotation marks); A package without escape.
In the syntax of go.mod, identifiers and strings are interchangeable.
Module Path and version
The identifiers and strings in go.mod are mostly Module Path and version.
The Module Path meets the following requirements:
- Contains one or more path elements (the smallest unit separated by a /) that do not start or end with a /
- The path element is a non-empty string consisting of ASCII letters/numbers/punctuation, punctuation contains
- _ ~
- The path element does not start or end
.
- Windows,
.
The preceding prefix cannot be a reserved filename:con/com1/nul
Etc.
When module path appears in the require directive, it is not replaced. Or if the Module path appears to the right of the replace directive, the go command may need to download the corresponding module, with the following additional requirements:
- The first path element (the part before /), by convention, can only contain lowercase ASCII letters/digits /
. -
- Contains at least one
.
You can’t start with /
- Contains at least one
- The last path element (the part after /) in /vN,N or numeric
- N cannot start with 0
- Can’t be/v1
- Cannot contain any
.
Ps: If the Module path starts with “gopkg.in/”, the above two requirements should be replaced with the requirements of gopkg.in.
Versions are standard and non-standard, with the standard beginning with V followed by the semantic version,eg: V2.1.1, and without build meta information except for “+incompatible”.
In this section, other identifiers and strings may appear in non-canonical versions. The module path restriction above is intended to reduce possible problems with “file system/repository /module proxy”.
The non-standard version can only appear in the main Module. The go command will automatically try to replace the non-standard version with the canonical version.
In the module path and version related places (eg: the require/replace/exclude instruction), the final path element must be the version.
grammar
Ebnf syntax:
GoMod = { Directive } .
Directive = ModuleDirective |
GoDirective |
RequireDirective |
ExcludeDirective |
ReplaceDirective |
RetractDirective .
ModulePath = ident | string . /* see restrictions above */
Version = ident | string . /* see restrictions above */
Copy the code
Ident /string/newline represents the identifier /string/newline respectively.
The module directive
The module directive defines the Module path of the main module. A go.mod contains only one module directive.
ModuleDirective = "module" ( ModulePath | "(" newline ModulePath newline ")" ) newline .
Copy the code
eg: module golang.org/x/net
Deprecated:
You mark the Module as Deprecated by starting it with Deprecated: in the comments section. Deprecated: The following section indicates the Deprecated message. Comments can appear on the line above or at the end of a Module directive.
// Deprecated: use example.com/mod/v2 instead.
module example.com/mod
Copy the code
After go1.17, Golist-m-u checks the build list for all deprecated modules; Go Get checks for deprecated modules on which it depends.
The correct way to deprecate is:
- Tag a newly released release
- Module is marked deprecated by its author
- Deprecation information indicates that the replacement is a new release
- On the new version of Relase, deprecation can be changed or cancelled
Deprecation is very useful for library developers. It is a communication tool with users. When users use commands such as golist-m-u, they will immediately discover the state of the library.
Deprecation is intended to remind the user that the current Module no longer provides support and migration guidance.
Do not discard the last version and retract is more appropriate.