This is a creation in Article, where the information may have evolved or changed.
Indispensable function, the way to define functions in Go is as follows:
func (p myType ) funcName ( a, b int , c string ) ( r , s int ) { return}
With function definitions, we can see the commonalities and features in functions and other languages in go.
Common
- Keyword--func
- Method Name--funcname
- Entry ——— A, b int,b string
- return value--r,s int
- function Body--{}
Characteristics
The function in Go is very cool and gives us a different programming experience.
Define a function for a specific type, that is, define a method for the type Object
In go, define a method for the type by giving it a type, which means that it p myType
declares a method to MyType, which p myType
is not required. If not, it is purely a function, accessed through the package name. Packagename.funcationname
Such as:
//defines a new type double, the main purpose of which is to give the float64 type the extension method type double float64//determine whether a is equal to Bfunc (a double) isequal (b Double) bool {var r = A-b if r = = 0.0 {return true} else if r < 0.0 {return R >-0.0001 } return R < 0.0001}//determine if a is equal to Bfunc isequal (A, b float64) bool {var r = A-b if r = = 0.0 {return true} else if r < 0.0 {return r > -0.0001} return R < 0.0001}func main () {var a double = 1 .999999 var b double = 1.9999998 fmt. Println (a.isequal (b)) fmt. Println (A.isequal (3)) fmt. Println (IsEqual ((float64) (a), (float64) (b))}
The above example expands the method isequal for the float64 base type, which mainly solves the accuracy problem. The method is called by: a.IsEqual(double)
If you do not extend the method, we can only use the functionIsEqual(a, b float64)
In the argument, if the successive parameter types are consistent, you can omit the type of multiple arguments consecutively, leaving only the last type declaration.
If func IsEqual(a, b float64) bool
This method preserves only one type declaration, both the entry A and B are float64 data types. This is also possible:func IsEqual(a, b float64, accuracy int) bool
Parameter: Parameters of the same type can be accepted with variable parameter
If the func Sum(args ...int)
parameter args is slice, its element type is int. Often used in FMT. printf is a function that accepts any number of argumentsfmt.Printf(format string, args ...interface{})
Support for multiple return values
Before we define the function, the return value has two r,s. This is very useful, when I write C # code, often in order to get more information from the existing functions, need to modify the function signature, using out, ref and other ways to get more return results. Now, with go, it is simple to add the return parameter directly after the return value.
For example, logical code when a string is converted to int type in C #
int v=0; if ( int.TryPase("123456",out v) ){ //code}
In go, it can be done, logically streamlined and clear
if v,isOk :=int.TryPase("123456") ; isOk { //code}
At the same time, many functions in go take advantage of multiple return values
- Func (file *file) Write (b []byte) (n int, err error)
- Func sincos (x float64) (sin, cos float64)
So what do I do if I only need a return value and don't care about the other return values? You can simply use the symbol underline "_" to ignore the return value that you do not care about. Such as:
_, cos = math.Sincos(3.1415) //只需要cos计算的值
Named return value
Before we say that the function can have more than one return value, what I want to say here is that all the return values can be named when the function is defined, so that you can copy the different return values anywhere in the function without specifying the return value in the return statement. It also enhances readability and improves the readability of documents generated by Godoc.
If the named return value is not supported, I might do so
func ReadFull(r Reader, buf []byte) (int, error) { var n int var err error for len(buf) > 0 { var nr int nr, err = r.Read(buf) n += nr if err !=nil { return n,err } buf = buf[nr:] } return n,err}
However, when the return value is supported, the declaration of the variable is omitted, and return does not need to be written, return n,err
but the value is returned directly
func ReadFull(r Reader, buf []byte) (n int, err error) { for len(buf) > 0 && err == nil { var nr int nr, err = r.Read(buf) n += nr buf = buf[nr:] } return}
Functions are also "values"
Like everything else in go, the function is also a value, so you can declare a variable of a function type and pass the function as a parameter.
A variable that declares a function as a value (anonymous function: Assignable variable or direct execution)
//赋值fc := func(msg string) { fmt.Println("you say :", msg)}fmt.Printf("%T \n", fc)fc("hello,my love")//直接执行func(msg string) { fmt.Println("say :", msg)}("I love to code")
The output is as follows, indicating that the FC is of type: Func (String)
func(string) you say : hello,my lovesay : I love to code
The function as a parameter (callback function), can bring convenience. such as log processing, in order to unify processing, the information through the specified function to record the log, and whether logging and switch
func Log(title string, getMsg func() string) { //如果开启日志记录,则记录日志 if true { fmt.Println(title, ":", getMsg()) }}//---------调用--------------count := 0msg := func() string { count++ return "您没有即使提醒我,已触犯法律"}Log("error", msg)Log("warring", msg)Log("info", msg)fmt.Println(count)
The output here is as follows, and count has changed.
error : 您没有即使提醒我,已触犯法律warring : 您没有即使提醒我,已触犯法律info : 您没有即使提醒我,已触犯法律3
The function is also a "type"
Did you notice the example above in FC: = Func (msg string) ...
Since an anonymous function can be assigned to a variable, we often assign a value to int value: = 2
, if we can declare the func (string) type, of course it is."
//A logging Type: func (String) type Savelog func (msg String)//convert string to Int64 if conversion fails call Savelogfunc Stringtoint (s string, log savelog) Int64 {if value, err: = StrConv. parseint (s, 0, 0); Err! = Nil {log (err. Error ()) return 0} else {return value}}//the specific implementation of logging message MyLog (msg string) {Fmt. Println ("Find Error:", msg)}func main () {Stringtoint ("123", MyLog)//conversion will call MyLog log stringtoint ("s", MyLog)}
Here we define a type that is specifically used as a standard interface for logging. In the Stringtoint function, if the conversion fails, call my own defined interface function for log processing, and for which function is ultimately executed, there is no need to care.
Defer delay function
Defer is also an innovation, its role is: Deferred execution, in the declaration will not be executed immediately, but after the return of the function in accordance with the principle of last-in-first-out in order to execute each of the defer. The advantage of this is that we can ensure that our defined functions are fully executed, so we can do a lot of things we want to do, such as freeing up resources, cleaning up data, logging logs, etc.
Here we focus on the execution order of the next defer.
func deferFunc() int { index := 0 fc := func() { fmt.Println(index, "匿名函数1") index++ defer func() { fmt.Println(index, "匿名函数1-1") index++ }() } defer func() { fmt.Println(index, "匿名函数2") index++ }() defer fc() return func() int { fmt.Println(index, "匿名函数3") index++ return index }()}func main() { deferFunc()}
The output here is as follows,
0 匿名函数31 匿名函数12 匿名函数1-13 匿名函数2
There are the following conclusions:
- Defer is executed after the return of the execution
- Defer backward First execution
In addition, we often use defer to close the IO, after the normal opening of the file, immediately declare a defer, so that you do not forget to close the file, but also to ensure that in the event of an unexpected exception, can also be closed file. And unlike other languages: try-catch
or using ()
mode for processing.
file , err :=os.Open(file)if err != nil { return err}defer file.Close() //dosomething with file
Later, I'll discuss: scope, pass-through and pass-through pointers, and reserved function init (), Main ()
The code that is written in this note is stored in the location:
- Defer.go
- Definefunctiontype.go
Transfer from http://www.cnblogs.com/howDo/archive/2013/06/04/GoLang-function.html