This is a creation in Article, where the information may have evolved or changed.
Catalogue [−]
- Built-in functions
- Package
- Import
- Initialization of the package
- Error, panic, and recover
This chapter describes the rest of the go language, which is the finishing touches to the Go language specification's in-depth learning.
Built-in functions
We've met several built-in functions in the previous chapters, and here we have a list of all the built-in functions.
If you look at their definitions, you can access the Builtin/builtin.go, but these built-in functions are only declared, there are no method bodies, they are not standard go types, and you cannot pass them as function values, only in the invocation expression. The fact that these built-in types are not really in the builtin package is only needed to generate documentation.
You can call these built-in functions in any package without introducing a specific package such as "BUILTIN".
1,close: Close channel
2.Len (s): Gets the length of the string, array, numeric pointer, slice, map, chan
3.cap (s): Get the length of array and array pointers, get the capacity of slice, channel
4,new (t): Generates a 0 value pointer of type T, note that it returns a pointer *t
5.make: Generate Slice, map, channel object
Call type T result make (t, N) slice slice of type T with length n and capacity nmake (T, N, m) slice Slice of type T with length n and capacity Mmake (t) map Map of type Tmake (t, N) map Map of type T, initial can accommodate n-ary The space Make (t) Channel does not have a cached channel of type T, such as when we declare the signal channel, make (t, N) channel with cached channel of Type T, cache size n
6,append (s S, x ... T) S: Add 0 to n elements to slice, return the new slice
7. Copy(DST, src []t) int: Copy the element of the source SRC slice to the target DST slice, return the number of copied elements n, n is the minimum value of SRC and DST lengths. The string can also be src, but the type of T must be byte
8. Delete(m,k): Delete a mapping in map, M nil or m[k] does not exist and will not panic, but an empty operation
9,complex,real,imag: Complex operation
10,panic,recover: report panic and deal with panic, the back said
11,print,println: Try not to use these two functions, because they are guaranteed to remain in the go language in the future, using FMT. Print, FMT. Println
Package
The Go code file will have the package definition in front of the import declaration.
All files under the same folder must use the same package name (of course, if you compile each file separately, you can not follow it, but to compile the entire project, you must follow).
However, the test file can be called a different package name, such as the normal code package named "Packages ABC", the package name of the test code and the sample code is "Packages Abc_test". Both styles are blended in the Go standard library.
mainA package is a special package that must declare a main function, the main function has no arguments, and no return value, which is used to create an executable program.
The package name is not necessarily the same as the name of the folder, often our project name is very long, not very suitable for the package name, so the package name can use a short name, but if possible, try to use the same name, so that the library can be downloaded until the name of the package.
Import
Import is used to introduce the required type, allowing you to access the export type in the other package.
The following four forms are acceptable mport:
Import declaration Local name of Sinimport "Lib/math" math. Sinimport m "Lib/math" m.sinimport. "Lib/math" sinimport _ "Lib/math"
To avoid package name collisions with the same name, you can name the imported package name, such as "M" in the previous example.
You can also use it so that you do . not need a package name identifier, you can use the export type directly under this package.
The last case is to use a null identifier, primarily to take advantage of the initialization of the package, rather than using its export type.
Imports cannot import packages themselves, either directly or indirectly (circular references). You cannot import a package directly without using its export type, fortunately some tools can automatically help us fix import errors, or automatically help us to import, such as Goimports.
Import can be imported relative paths, such as "Import \". /foo/bar\ "", but strongly you don't want to do this, this is not the usual import style.
Import can enclose multiple packages in parentheses.
Initialization of the package
Package variables are initialized in the same order as they are declared, but they also have to be considered for their dependencies.
Cyclic dependency initialization is also not possible:
12345 |
Package ABCvarint = Jvarint = kvarint = i |
After the initialization of the package variable can call an init function to implement other initialization process, you can display the definition of this function, it can appear in multiple files under the same package, the order of execution is determined by the compiler.
If the package imports additional packages, the imported packages are initialized first. If more than one package is imported into the same package, the imported package is initialized only once.
Error, panic, and recover
Go pre-Defines the error type, although its initials are not uppercase, but can be used under any package:
123 |
type Interface string} |
The errors package defines a method for generating simple error errors.New(text String) error . If you want to customize the error type, you can implement the error interface.
Runtime error, such as array index out of bounds, triggers a runtime panic, which is equivalent to calling the panic function, and the value of panic is a runtime. Error:
123456 |
Package Runtimetypeinterface {error//And perhaps other methods} |
The processing of panic is performed in a defer function:
12345678910111213141516 |
func Main () {deferfunc() {fmt. Println ("foo")} ()deferfunc() {ifrecovernil {fmt. PRINTLN (x)}} ()deferfunc() {fmt. Println ("Bar")} ()panic("trigger Panic") FMT. Println ("End")} |
Note that the order of execution of defer, as previously stated, is the opposite of the order in which they are declared, so the output is:
The last sentence has no opportunity to continue because the function terminates after recover executes.
This poses a problem, if the function has a return value, what is the return value of the function after recover?
12345678910111213141516171819202122
|
func main () {i: = Z () fmt. Println (i)}func z () int {defer func () {fmt. Println ( "foo" )} () defer func () {if x: = recover (); x! = Nil {FMT. PRINTLN (x)}} () defer func () {fmt. Println ( "bar" )} () panic ( "trigger Panic ") fmt. Println ( "end" ) return + } |
The output is:
The return of a function can be a 0 value of the return type.
Of course, the value of 0 is not exactly correct, if the function has a named return parameter, and the named return parameter is assigned before panic, the returned result is the final assignment result, the function in the following code returns the result is 50:
1234567891011121314151617181920212223 |
func main () {i: = Z () fmt. Println (i)}func z () (R int ) { Defer func () {fmt. Println ( "foo" )} () defer func () {if x: = recover (); x! = Nil {FMT. PRINTLN (x)}} () defer func () {fmt. Println ( "bar" )} () R = panic () fmt. Println ( "end" ) return + } |
The
Panic, if not processed, is passed to its caller, which is the bubble of panic. Of course, if you can foresee panic, the best way to deal with this is to do it inside this function, because you can't control the behavior of the external caller, and the external caller doesn't necessarily know that there's a panic happening:
123456789101112131415161718192021222324252627 |
func main () {defer Func () {if x: = recover (); X! = nil {FMT. Println ( "Recover from main:" , X)}} () F1 ()}func F1 () {FMT. Println ( "start F1" ) F2 () fmt. Println ( "end F1" )}func f2 () {fmt. Println ( "start F2" ) F3 () Fmt. Println ( "end F2" )}func f3 () {fmt. Println ( "start F3" ) panic ( " Triggered from F3 ") fmt. Println ( "end F3" )} |
The above code output:
1234 |
start F1start f2start from from F3 |
If no recover is attached to main, the program exits unexpectedly.
and a less noticeable area is what happens if you produce panic in recover? Or look at an example:
123456789101112131415161718192021222324 |
func main () {defer func () {if x: = recover (); x! = Nil {FMT. Println ( "Recover from main:" , X)}} () F1 ()}func F1 () {defer func () {if x: = recover (); X! = nil {fmt. Println ( "Recover from F1:" , x) panic ( "triggered from F1" )}} () F2 ()}func f2 () {panic ( " Triggered from F2 ")} |
The panic generated by the
function F2 is handled F1 by the function, F1 generates a new recover during the panic, which captures its caller main.
So the panic generated by recover will be passed up.