This is a creation in Article, where the information may have evolved or changed.
function func
function Declaration the basic composition of the function is: the keyword func, the function name, the argument list, the return value, the function body, and the return statement.
General: Func function name (incoming parameter) (return parameter) {function Body}
Such as:
Package Mymathimport "Errors" func Add (a int, b int) (ret int, err error) {if a < 0 | | b < 0 {//Suppose this function only supports addition of two nonnegative numbers err= errors. New ("should be non-negative numbers!") return} return a + B, nil//support multiple return values}
if several adjacent parameter types are the same in the parameter list, you can omit the type declaration of the preceding variable, such as:
Func Add (A, B int</span>) (ret int, err error) {//...}
if more than one return value in the return value list is of the same type, it can be combined in the same way.
If the function has only one return value, you can also write this:
Func Add (A, b int) int {//...}
function Call 1. Import the package containing the function
2, the following call
Import "MyMath"//Assume that add is placed in a package called MyMath//... c: = MyMath. ADD (1, 2)
It is important to note that if you want to call the package function externally, the function name you call must be capitalized.
The Go language has this rule:
Functions that begin with lowercase letters are visible only within this package, and functions that begin with uppercase letters can be used by other packages.
This rule also applies to the visibility of types and variables.
Indeterminate parameters
An indeterminate parameter is a variable number of arguments passed in by a function. To do this, you first need to define the function to accept the indeterminate parameter type:
Func myfunc (args ... int) {//Parameter name ... type for _, arg: = Range args {fmt. Println (ARG)}}
The function can receive an indefinite number of parameters, such as:
MyFunc (2, 3, 4) MyFunc (1, 3, 7, 13)
From the internal implementation mechanism, the type ... type is essentially an array slice, that is, []type, which is why the above parameter, args, can use a for loop to get each incoming parameter.
If there is no such grammatical sugar as the type, the developer will have to write:
Func myfunc2 (args [] int) {For _, arg: = Range args {fmt. Println (ARG)}}
From the point of view of the function implementation, this has no effect, how to write it. But from calling Towners, the situation is completely different:
MYFUNC2 ([] int{1, 3, 7, 13})
You will find that we have to add []int{} to construct an array tile instance.
Transfer of indeterminate parameters
Func myfunc (args ... int) {//pass MYFUNC3 as-is (args ...) Passing fragments, virtually any int slice can be passed in myfunc3 (args[1:] ...)}
Indefinite parameters of any type
The previous example constrains the indeterminate parameter type to int, and if you want to pass any type, you can specify a type of interface{}.
Here is the fmt,printf () function prototype in the Go language:
Func Printf (format string, args ... interface{}) {//...}
The following code allows us to clearly know the type of incoming parameters:
Package Mainimport "FMT" func myprintf (args ... interface{}) {for _, arg: = range args {switch arg. (type) {case int : FMT. Println (ARG, "is a int value.") Case string:fmt. Println (ARG, "is a string value.") Case int64:fmt. Println (ARG, "is an Int64 value.") default:fmt. Println (ARG, "is an unknown type.")} }}func Main () {var V1 int = 1 var v2 int64 = 234 var v3 string = "Hello" var v4 float32 = 1.234 myprintf (v1, v2, v3, v4)}
The output of this program is:
1 is an int value.234 are an int64 Value.hello are a string value.1.234 is an unknown type.
anonymous functions and closures
In go, a function can be passed or used like a normal variable, which is similar to the C-language callback function. Different
Is that the Go language support defines anonymous functions in the code at any time.
An anonymous function consists of a function declaration and a function body without a function name, as follows:
Func (A, b int, z float64) bool {return a*b <int (z)}
Anonymous functions can be directly assigned to a variable or executed directly:
F: = func (x, y int) int {return x + y}func (ch chan int) {ch <-ACK} (Reply_chan)//curly brace directly followed by argument list representing function call
Closed Package
Closures are blocks of code that can contain variables that are free (not bound to specific objects) that are not within this block of code or
Defined in any global context, but in the context in which the code block is defined. The code block to execute (because the free variable contains
In the code block, so these free variables and the objects they refer to are not freed) to provide a binding calculation ring for the free variable
Environment (SCOPE).
This is the official statement, my understanding is:
Simply put, it is a closed func, it can access the variable it declares externally, but the externally cannot access the variable it declares internally unless it is willing to provide a handle
Closures in the Go language also refer to variables outside the function. Closures are implemented to ensure that as long as closures are used,
Variables referenced by closures will always exist, such as:
Package Mainimport ("FMT") func main () {var J int = 5 A: = Func () (func ()) {var i int = ten return func () {fmt. Printf ("I, J:%d,%d\n", I, J)}} () A () J *= 2 A ()}
The result of the above example is:
I, J:10, 5i, J:10, 10
In the above example, the closure function that the variable a points to refers to the local variables I and J, the value of I is isolated, and the outside of the closure does not
Can be modified, after changing the value of J, call a again to find that the result is a modified value.
In the closure function that the variable a points to, only the internal anonymous function can access the variable I and cannot be accessed by other means
To ensure the safety of I.
Error handling
The error handling of the go language is very convenient, introducing a standard error-handling interface:
Type Error Interface {error () string
In general, the function returns an error that can be set to the last of the return value:
Func Foo (param int) (n int, err error) {//...}
We use the error message by judging whether err is nil or not:
N, Err: = Foo (0) If err! = Nil {//error handling} else {//Use return value n}
So how do we implement our own error message types:
Type patherror struct {//parameter name uppercase, outside struct can view Op string Path string ERR Error}
We then implement an error () method for the struct, (why error capitalization)
Func (e *patherror) Error () string {return E.op + "" + E.path + ":" + E.err.error ()}
So we can wrap the error message ourselves.
Func stat (name string) (Fi FileInfo, err error) {var stat syscall. stat_t err = Syscall. Stat (name, &stat) if err! = Nil {//stat return error message returned by Patherror return nil, &patherror{"stat", Name, err}} return fil Einfofromstat (&stat, name), nil}
If you get detailed information when dealing with an error, rather than just printing an error message, you need to use the type
Change of Knowledge:
FI, err: = OS. Stat ("A.txt") if err! = Nil {if e, OK: = Err. ( *os. PATHERROR); OK && e.err! = Nil {//Get additional information in Patherror type variable e and process}}
defer
Defer keyword: delay function. After the function return, it can be executed before the function ends.
The obvious difference from C + + is that, for example, opening a file input stream needs to be closed in time. No one programmer can do hundred percent, and defer is a good implementation of this function
Func CopyFile (DST, src String) (w Int64, err error) {srcfile, err: = OS. Open (SRC) if err! = nil {return} defer Srcfile.close () dstfile, err: = OS. Create (dstname) if err! = nil {return} defer Dstfile.close () return IO. Copy (Dstfile, Srcfile)}
Even if the copy () function throws an exception, go still guarantees that dstfile and Srcfile will be shut down normally.
You can also use an anonymous function after defer if you feel that a sentence does not finish the cleanup work:
Defer func () {//Do your complex cleanup work} ()
In addition, multiple defer statements can exist in a function, so it is important to note that the invocation of the defer statement is in accordance with the
The advanced post-out principle, that is, the last defer statement will be executed first. Just when you need a defer statement exactly where
When you worry about doing this detail first, it means that your code architecture may need to be adjusted.
panic () and recover () The go language introduces two built-in functions panic () and recover () to report and handle run-time errors and bugs in the program
False scene:
Func Panic (interface{}) func recover () interface{}
When you call the Panic () function during a function execution, the normal function execution process terminates immediately, but the function
Statements that were previously deferred with the DEFER keyword are executed normally, and then the function returns to the calling function and causes
Executes the panic process up and down until all the executing functions in the owning goroutine are terminated. The error message will be reported
Called the Panic () function, which is known as the error-handling process.
From the parameter type of panic () interface{} We can tell that the function receives any type of data, such as an integer
Type, string, object, and so on. The invocation method is simple, and here are a few examples:
Panic (404) Panic ("Network Broken") Panic (Error ("File Not exists")
The Recover () function is used to terminate the error handling process. In general, recover () should be used in one of the defer
keyword function to effectively intercept the error-handling process. If recovery is not explicitly called in the goroutine that the exception occurred
Procedure (using the Recover keyword) causes the process that the goroutine belongs to print exception information and exit directly.
Our execution of the Foo () function either has a feeling that it may trigger error handling, or it explicitly adds
Into a statement that triggers error handling on a specific condition, you can intercept recover () in the calling code as follows:
Defer func () {if r: = Recover (); r! = Nil {log. Printf ("Runtime Error Caught:%v", R)}} () foo ()
Whether or not the error-handling process is triggered in Foo (), the anonymous defer function will be executed when the function exits. False
If the error handling process is triggered in Foo (), the Recover () function execution will terminate the error handling process. If the error is located
When the process is triggered, the parameter passed to the panic function is not nil, and the function also prints a detailed error message.