Go core development study notes (xiv) - init function, anonymous functions, closures, defer

init function

  1. Each source file can contain an init function, which will be executed before the main function, is called Go run frame.

  2. Generally used to do the initial work before the main function is run.

  3. File contains a global variable definitions, init (), main (), then the execution order: a global variable definition -> init () -> main ().

  4. Enhanced version of article 3, in the main folder in the non-src, a write function, the introduction of two variables, and the writing init () function, so at this time becomes the order of:
    non-main import the package init () - > global variable defined in main -> init () -> main ().

  5. Article 4 of the enhanced version, if src non-main is called there is a global variable definition and function init (), src main file contains global variables defined, init (), main (), which is what the five should be the order of execution:
    non the main import the global variable definition package -> of the non-main import package the init () -> main global variable defined in -> init () -> main ().

    Referring to the schematic of FIG.

    package main 
    import "<被调用函数>"    //①全局变量定义 ②init()                      
    ③ <全局变量定义>
    ④ func init {
          \<函数体>
    }
    ⑤func main {
    		 \<函数体>
    }
    

Anonymous function:

  1. Usage scenarios: Generally used only once on OK, to call just once
  2. Directly call when defining an anonymous function in this way can only be called once, case presentations:
    package main
    
    import "fmt"
    
    func main() {
    	//直接在创建匿名函数时直接调用,注意下匿名函数格式,传参在函数定义后直接传
    	res := func (n1,n2 int) int {
    		return n1+n2
    	} (10,20)
    	fmt.Println(res)
    }
    
  3. Anonymous functions may be assigned to a variable, is defined by the use of <variable> (para1, para2) mode after a good parameter.
  4. Variable is defined in the full amount in a variable, the data type is an anonymous function, can be above, main () in any one place can use the anonymous function.
  5. Advantages anonymous function is the main () function if there are other defined function name is not allowed, so a high flexibility anonymous function.

Closure

  1. Closure is a whole function associated with a reference to the composition of the environment.
  2. Closure return value is a function that will use some variables outside of functions, which together form a whole, this whole package called the closure.
  3. Can be understood, the closure is a class, a function of external variables define properties seen, the function returns the value as defined method, constitute class attributes and methods, i.e. closure.
  4. Key figure out closure is to analyze the function and variable return it refers to, constitute closures, each call to the function outside environment variable is not re-initialized, but accumulate.
    Case:
    package main
    
    import "fmt"
    
    func Addpp() func(int) int {       //定义一个函数 传入的参数是一个func, 返回值为int
    	var n int = 20
    	var str string = "shit!"
    	return func (x int) int {      //Addpp返回值是一个匿名函数,相当于一个累加器了
    		n = n + x
    		str += " damn!"
    		fmt.Println("str= ",str)
    		return n
    	}
    }
    func main() {
    	/*
    		理解闭包的概念,闭包本身是一个函数,闭包的返回值也是一个函数,return func;
    		return 的是一个匿名函数,匿名函数中会调用闭包函数中的变量,从而做一些事情,产生返回值;
    		被匿名函数返回的返回值是匿名函数外的变量,则变量会改变初始化的值
    	*/
    	f := Addpp()
    	fmt.Println(f(1))
    	fmt.Println(f(2))
    	fmt.Println(f(3))
    }
    
  5. Case: using closures pass a complete file name, file name suffix .jpg if do not modify, direct output; if there is no extension will be the file name plus the .jpg Output:
    determines whether the file name suffix, use strings.HasSuffix ()
    code is as follows:
    package main
    import (
    	"fmt"
    	"strings"           //使用strings包的HasSuffix方法判断文件是否有后缀
    )
    
    func makeSuffix (suffix string) func (string) string {            //makeSuffix()实现功能是添加后缀名,返回值为一个函数
    	return func (fileName string) string {                        //
    		if !strings.HasSuffix(fileName,suffix) {
    			fileName += suffix
    			return fileName
    		}
    		return fileName
    	}
    }
    
    func main() {
    	/*
    	案例:使用闭包完成传入一个文件名,如果文件名有后缀.jpg就不用修改,直接输出;如果没有后缀就将文件名加上.jpg输出:
    	         判断文件名是否有后缀,使用strings.HasSuffix()
    	 */
    	var fileName string
    	fmt.Println("请输入传入值的文件名称: ")
    	fmt.Scanf("%s",&fileName)
    	f := makeSuffix(".avi")
    	fmt.Println(f(fileName))
    }
    

defer
in the function, programmers often need to create resources (database connections, locks, handles, etc.), in order to function after the execution is complete, timely release of resources, open, establish the connection immediately defer xxclose

  1. When performing the defer, it is not performed, the latter will be pressed into the defer statement independent stack (Stack defer).
  2. When the function completes, then defer from the stack, last-out manner from the stack, performs.
  3. When the push statement, the correlation value will be copied to the stack, for example, the statement after the change value N1 + defer the like, according to the push time, not + follow N1, as the value of the transfer function.
    Example:
    package main
    import "fmt"
    func sum (n1,n2 int) int {                
    	defer fmt.Println("n2 is OK",n2)         //压栈,辅函数中输入defer,函数结束后本条第二个执行
    	defer fmt.Println("n1 is OK",n1)         //压栈,根据压栈方式可以判定,函数结束后本条第一个执行
    
    	res := n1 + n2
    	fmt.Println("sum is finished")        //终端最先输出的是这句话
    	return res
    }
    func main() {
    	f := sum(10,20)
    	fmt.Println("res的值为",f)             //最后输出的是这句话
    }
    
  4. As can be seen by the above example, if the pod can understand k8S studied there before starting a pre-start, there is a subsequent post-stop, a pods before something starts to be configured, the other is terminated after the pods, what should I do.
  5. The main value is to defer after the function is finished, the timely release of resources to create a function, such as connecting to the database, or open the file, enter the resource immediately defer closed, so peace of mind to deal with things, over natural resources processing functions shut down, good design .
    Analog:
    FUNC {the Test
    File = OpenFile (<filename>)
    the defer File.close () // write immediately, without affecting the function is executed or when a persistent connection and use Close
    }

Tips:

  1. func sum (n1, n2 float32) {...} // Note that in this way with no problems, n1 is float32 format, compile error does not occur.

  2. The called function is possible parameter values ​​passed by reference or passed depending on whether needs to change shape, if the value is passed directly basic variable types, if a pointer is passed by reference is used.

    Case: Write a function that compares the number three sizes, from small to large output

    The called function:

    package compare
    func Compare(a *int,b *int,c *int)  {
        var temp int
    	if *a > *b {
    		temp = *a
    		*a = *b
    		*b = temp
    	}
    	if *a > *c {
    		temp = *a
    		*a = *c
    		*c = temp
    	}
    	if *b > *c {
    		temp = *b
    		*b = *c
    		*c = temp
    	}
    }
    

    call function:

    package main
    
    import (
    	"compare"
    	"fmt"
    )
    
    func main() {
    	var (
    		a int
    		b int
    		c int
    	)
    	fmt.Println("请输入三个数,用空格间隔开:\n")
    	fmt.Scanf("%d %d %d",&a,&b,&c)
    	compare.Compare(&a,&b,&c)
    	fmt.Printf("三个数从小到大排列为:%v %v %v",a,b,c)
    }
    
Published 50 original articles · won praise 18 · views 4015

Guess you like

Origin blog.csdn.net/weixin_41047549/article/details/89714567