Golang basis _06- function function

table of Contents

@

Tips

  • Go function does not support nested, overloading and default parameters
  • But supports the following features: no prototype declaration indefinite length varying parameter, multi-return value, the return value of the parameter name, anonymous function, closure
  • Defined functions using the keyword func, and the opening brace can not start a new line

    Function definition, variable length varying parameter passed value type and reference type

func main(){
    a,b := 1,2
    //传入值类型的拷贝,(int,string),不会改变这里的值
    B(a,b)
    fmt.Println("a,b=",a,b)
    fmt.Println(A())
    ss := []int{5,6,7,8}
    //传入的参数是slice,是数组地址的拷贝,会改变这里的值,类似指针
    C(ss)
    fmt.Println("ss=",ss)
}
func A()(int, int, int){
    a,b,c := 1,2,3
    return a,b,c
}
func B(s ...int){
    //a是个slice,不定长变参,只能作为最后一个参数
    s[0]=3
    s[1]=4
    fmt.Println("s=",s)
}
func C(s []int){
    s[0] = 55
    s[1] = 66
    s[2] = 77
    s[3] = 88
    fmt.Println(s)
}
/*
> Output:
command-line-arguments
s= [3 4]
a,b= 1 2
1 2 3
[55 66 77 88]
ss= [55 66 77 88]
*/
  • Passed value type and reference type of transmission is copied, but the value is copied type value, and a reference copy of the address type

    Everything types, including functions

  • Go languages, and all are types, functions can also be used as a type

func main(){
    a := A
    a()
}
func A(){
    fmt.Println("Func A")
}
/*
> Output:
command-line-arguments
Func A
*/

Anonymous functions and closures

Anonymous function

- anonymous function is not a function of the outermost layer

func main(){
    a := func(){
        fmt.Println("Func A")
    }
    a()
}
func A(){
    fmt.Println("Func A")
}
/*
> Output:
command-line-arguments
Func A
*/

Closure

  • Effect closure function: function returns an anonymous
func main(){
    f := closure(10)
    fmt.Println(f(1))
    fmt.Println(f(2))
}
func closure(x int) func(int) int {
    fmt.Printf("outside %p\n", &x)
    return func(y int) int {
        fmt.Printf("%p\n", &x)
        return x * y
    }
}
/*
> Output:
command-line-arguments
outside 0xc042054080
0xc042054080
10
0xc042054080
20
*/

defer usage

  • similar to defer implementation destructor other languages, after performing the function thereof, according to the call order reverse order execution (as if it returns a recursive)
  • Even if the function will perform a serious error has occurred
  • It supports the use of anonymous functions
  • Commonly used in the resource cleanup, the file is closed, unlocked and recording time and other operations
  • You can modify the function result after the return through cooperation with an anonymous function
  • If the address of the function body of a variable as a parameter when defer anonymous function at the time of definition has received a copy, otherwise it is a reference to a variable
func main(){
    fmt.Println("a")
    defer fmt.Println("b")
    defer fmt.Println("c")
}
//a,c,b
  • The return statement seen assignment + RET instruction to return the two parts, is inserted in the middle defer and defer attention inside the return value of the function or operation of the other variables, parameters are passed by value anonymous function or passed by reference, to the value transfer The return value will not change it
  • Referring to chiefs resolved
  • Note: defer later defined anonymous functions to add at the end (parameter)
func main(){
    for i:=0; i<3; i++ {
        defer func() {
            fmt.Println(i)
            }()
    }
    fmt.Println("a")
    defer fmt.Println("b")
    defer fmt.Println("c")
}
/*
> Output:
command-line-arguments
a
c
b
3
3
3
*/

panic and recover, error handling mechanism

  • Go no exception mechanism, but panic / recover mode to handle errors
  • panic can lead to anywhere, but recover only defer function call
func main(){
    A()
    B()
    C()
}
func A() {
    fmt.Println("Func A")
}
//defer要放在panic前面才有效,程序遇到panic就停了,所以要在这之前先注册defer的函数,且panic语句也不会执行了
func B() {
    defer func() {
        if err:=recover(); err!=nil{
            fmt.Println("recover in B")
        }
    }()
    panic("panic in B")
}
func C() {
    fmt.Println("Func C")
}
/*
> Output:
command-line-arguments
Func A
recover in B
Func C
*/

Comprehensive example

func main(){
    var fs = [4]func(){}
    for i := 0; i<4; i++ {
    //值拷贝i+defer先进后出的输出
        defer fmt.Println("defer i= ",i)
        //引用拷贝(匿名函数没有参数,引用的i是外层的地址拷贝,为4)+defer
        defer func() {fmt.Println("defer_closure i= ",i)}()
        //引用拷贝(匿名函数没有参数,引用的i是外层的地址拷贝,为4)
        fs[i] = func(){ fmt.Println("closure i= ",i)}
    }
    for _,f := range fs {
        f()
    }
}
/*
> Output:
command-line-arguments
closure i=  4
closure i=  4
closure i=  4
closure i=  4
defer_closure i=  4
defer i=  3
defer_closure i=  4
defer i=  2
defer_closure i=  4
defer i=  1
defer_closure i=  4
defer i=  0
*/

Guess you like

Origin www.cnblogs.com/leafs99/p/golang_basic_06.html