05 Functions, packages and error handling

function

Complete a certain functional program instruction set
definition grammar

func 函数名(形参列表)(返回值列表){
    
    
	 执行语句
	 return 返回值列表
}

Sample code

func main () {
    
    
	fmt.Println("结果==",cal(1.1,3.0,'+'))//4.1
}
func cal ( n1 float64, n2 float64,opreator byte)( float64){
    
    
	var res float64
	switch opreator {
    
    
		case '+':
			res = n1 + n2
		case '-':
			res = n1 - n2
		case '*':
			res = n1 * n2
		case '/':
			res = n1 / n2
		default:
			fmt.Println("操作符不正确")

	}
	return res

}

Multi-value return code example

func main () {
    
    
	//fmt.Println("结果==",util.Cal(1.1,3.0,'+'))//4.1
	res1,res2 := getSumAndSub(1,2)
	res3,_ := getSumAndSub(1,2)
	fmt.Println(res1,res2,res3)
}
func getSumAndSub(n1 int ,n2 int)(int,int){
    
    
	sum := n1 + n2
	sub := n1 - n2
	return sum,sub
}
//声明返回值名称
func getSumAndSub2(n1 int ,n2 int)(sum int,sub int){
    
    
	sum = n1 + n2
	sub = n1 - n2
	return 
}
//可变参数
func getSum(n1 int,args... int) int {
    
    
	var res int = n1
	for i :=0 ; i<len(args); i++{
    
    
		res += args[i]
	}
	return res
	
}

important point

  1. In function transfer, the basic data types and arrays are all value transfers by default, that is, the value is copied, and the modification in the function does not affect the original value. If you want the change of the value in the function to affect the value outside the function, you can pass in the address &num, function Manipulate variables in the way of pointers
  2. Go does not support function overloading
  3. Functions in Go are also a type that can be assigned to variables, and functions can be called through variables
  4. Functions can be passed into functions as formal parameters
  5. Supports naming the return value of the function, after naming the return, there is no need to append a value to return. Automatically return the declared return value variable
  6. Go functions support variable parameters

package

Used to distinguish function variables with the same name, to better manage the scope of code files, control function variables, etc.
Each folder in go is a package

important point

  1. When packaging a file, the package corresponds to a folder, such as package utils and package main in the example, which are usually the same as the folder, generally in lowercase letters
  2. When a file needs to use functions or variables of other packages, you need to import the corresponding path first, such as import go01/utils in the example. When importing the package, the Go compiler will automatically search for the path from the src under GOPATH and import the content.
  3. If the method variables in the package are to be referenced by other packages, the first letter must be capitalized
  4. Use the package name and function name method when calling other package contents
  5. If the package name is very long, it can be aliased when importing, such as: import util “go01/utils”. After taking the package name, the original package name cannot be used.
  6. Under the same package, there cannot be the same function name or variable name, otherwise it will prompt repeated definition
  7. If you want to compile into an executable program file, you need to declare the package as main. This is a grammatical specification. If it is compiled into a library, the package name can be customized

Code sample
go01/main under main.go

package main
import (
	"fmt"
	util "go01/utils"
)
func main () {
    
    
	fmt.Println("结果==",util.Cal(1.1,3.0,'+'))//4.1
}

under go01 / utils util.go

package utils

import (
	"fmt"
)

func Cal ( n1 float64, n2 float64,opreator byte)( float64){
    
    
	var res float64
	switch opreator {
    
    
		case '+':
			res = n1 + n2
		case '-':
			res = n1 - n2
		case '*':
			res = n1 * n2
		case '/':
			res = n1 / n2
		default:
			fmt.Println("操作符不正确")

	}
	return res

}

init function

Each file can contain an init function, which is used for the initialization work before execution. Before the function is executed in the main function, it will be called by the Go runtime framework.
be careful

  1. If a file contains global variable definitions at the same time, the execution order of init function and main function is: global variable definition -> init function -> main function
  2. If main.go calls util.go and both include the init method and global variable definitions, the order of execution is: uitl variable definition ->util init ->main variable definition ->main init method -> main main method

Example

func init(){
    
    
	fmt.Println(" main init被执行...")
}

Anonymous function

An anonymous function is a function without a name. If a function is used only once, consider using an anonymous function. The anonymous function can also be called multiple times in the
sample program

func test1(){
    
    
	//定义好函数后直接调用
	res1 := func(n1 int,n2 int) int {
    
    
		return n1 + n2
	}(1,2)
	fmt.Println(res1)
	//将匿名函数赋值给 变量 然后通过变量调用,
	//如果将函数赋值给 全局变量那么 函数可以全局调用
	a := func(n1 int,n2 int) int {
    
    
		return n1 + n2
	}
	fmt.Println(a(1,2))
}

Closure

A closure is a combination of a function and its related reference environment as a whole.
Test code

func test2(){
    
    
	f1 := AddUpper(5);
	fmt.Println(f1(1))
	fmt.Println(f1(2))
}

// 定义一个函数 AddUpper 传入一个初始值 ,返回一个函数 
// 函数调用时在 初始值基础上增加固定值


func AddUpper(n1 int) func(int) int{
    
    
	var n int = n1
	return func (x int) int{
    
    
		n = n + x
		return n
	}
}

Function defer

In functions, programmers often need to create resources (database connections, locks, etc.), and the corresponding resources must be released after the function is executed. Go provides a defer delay mechanism to achieve this. More convenient to
pay attention to

  1. When go executes to refer, the statement after defer will not be executed immediately, but the statement after defer will be pressed onto a stack, and then the next statement will be executed
  2. After the function is executed, the statements are sequentially taken out from the defer stack and executed.
  3. When defer puts the statement on the stack, it also copies the related value to the stack. The change of the value type variable in the method does not affect the value in the stack

Sample code

func test3(n1 int,n2 int ) int {
    
    
	defer fmt.Println("ok1 n1=",n1)//10
	defer fmt.Println("ok2 n2=",n2)//20
	n1++
	n2++
	res := n1 + n2
	fmt.Println("res =",res)//32
	return res
}

Variable scope

  1. The scope of the variable defined in the function or statement block is this statement block
  2. The variable declared outside the function is a global variable, the scope is the real package, if the first letter is capitalized, the scope is the entire program

Commonly used functions

String commonly used functions

func test02(){
    
    

	var str = "hahaz中文1243";
	fmt.Println("字符串长度",len(str))
	//字符串遍历 同时处理有中文的问题
	r := []rune(str)
	for i :=0;i<len(r);i++{
    
    
		fmt.Printf("字符=%c",r[i]) 
		fmt.Println("") 
	}
	//字符串 转整型
	n,err := strconv.Atoi("12")
	fmt.Println("转整型:",n,err) 
	//整数转字符串
	n2 := strconv.Itoa(12)
	fmt.Println("转字符串:",n2) 
	//字符串 转 byte数组
	var tytes = []byte(str)
	fmt.Println("转字[]byte:",tytes) 
	//  byte数组 转 字符串
	var str2 = string(tytes)
	fmt.Println("[]byte转字符串:",str2) 
	//10进制转 2、8、16进制
	str2 = strconv.FormatInt(16,2)
	fmt.Println("2进制:",str2) 
	str2 = strconv.FormatInt(16,8)
	fmt.Println("8进制:",str2) 
	str2 = strconv.FormatInt(16,16)
	fmt.Println("16进制:",str2) 

	//字符串包含
	fmt.Println("是否包含:",strings.Contains("seafood","foo")) 
	fmt.Println("包含子字符串数量:",strings.Count("seafood","foo")) 
	fmt.Println("是否相同:",strings.EqualFold("Foo","foo")) 
	fmt.Println("子字符串第一次出现位置:",strings.Index("seafood","foo")) 
	fmt.Println("转大写:",strings.ToLower("sSEafood")) 
	fmt.Println("转小写:",strings.ToUpper("seafood")) 
	fmt.Println("去除两端空格:",strings.TrimSpace("  seafood  ")) 
	fmt.Println("去除两边空格和指定字符:",strings.Trim("sssesafoodsss","s")) 
	fmt.Println("去除左边空格和指定字符:",strings.TrimLeft("sssseafoodsss","s")) 
	fmt.Println("去除右边空格和指定字符:",strings.TrimRight("sssseafoodsss","s")) 
	fmt.Println("子字符串最后出现的位置:",strings.LastIndex("se123afood123","123")) 
	fmt.Println("替换字符串:",strings.Replace("se123afood123","123","1~3",-1))
	fmt.Println("判断字符串开头:",strings.HasPrefix("http://123.com","http"))
	fmt.Println("判断字符串结尾",strings.HasSuffix("http://123.com","com"))
	fmt.Println("字符串拆分========")
	strArr := strings.Split("zhagnsna,lisi",",")
	for i:=0;i<len(strArr);i++{
    
    
		fmt.Println(strArr[i])
	}

}

Time and date functions

func test03(){
    
    
   now := time.Now()
   fmt.Printf("当前时间 :%v,type: %T",now,now)
   fmt.Println()
   fmt.Println("当前时间信息:",now.Year(),now.Month(),now.Day(),
   now.Hour(),now.Minute(),now.Second())

	//Printf格式化时间 
	fmt.Printf("当前时间 :%d年%d月%d日%d时%d分%d秒",
	now.Year(),now.Month(),now.Day(),now.Hour(),
	now.Minute(),now.Second())
	fmt.Println()
	//time.Format 格式化日期 格式中的数字不能变 2006-01-02 15:04:05
	fmt.Println("当前时间:"+now.Format("2006-01-02 15:04:05"))

	//每100毫秒打印一个数字 
	for i:=0;i<10;i++{
    
    
		fmt.Println(i)
		time.Sleep(time.Millisecond * 100)
	}
	
	//h获取 从 1970年1月1日到指定时间 经过的时间  单位分别为秒和纳秒
	fmt.Printf("unix时间戳:%v unixnano时间戳:%v \n",now.Unix(),now.UnixNano())
	fmt.Println()

	fmt.Println()
}

Built-in functions
Golang provides some functions for the convenience of programming, which can be used directly. We call them built-in functions.

  1. len: used to find the length such as: string, array, slice, map, chnnel
  2. new: used to allocate memory, mainly used to allocate value types, such as: int float32, struc returns a pointer
  3. make: used to allocate memory, mainly used to allocate reference types, such as channel map slice
func test04(){
    
    
	fmt.Println(len("123"))

	num := new(int) // *int 类型
	*num = 100
	fmt.Printf("num 类型 %T,num 的值 %v,num 地址 %v  %v \n",
	num,*num,&num,*num)

}

Error handling

By default, after an error occurs, the program will exit. We can capture and process the error and set a reminder to the administrator (email\SMS)

  1. Golang pursues an elegant introduction, so it does not support the traditional try catch finally statement
  2. Through defer panic recover, the program ran out a panic exception. In defer, the exception was caught and processed by recover.
  3. Golang supports custom errors,
func test05(){
    
    
	defer func(){
    
    
		err := recover()
		if err != nil{
    
    
			fmt.Println("err=",err)
		}
	}()
	num1 :=10
	num2 :=0
	res :=num1/num2
	fmt.Println("res=",res)
}

//抛出自定义异常
func test06(){
    
    
	defer func(){
    
    //处理异常
		err := recover()
		if err != nil{
    
     
			fmt.Println("test 06 err=",err)
		}
	}()
	err :=errTest("hei")
	if err != nil {
    
    
		panic(err)//抛出异常
	}
	fmt.Println("抛出异常后还能执行吗")

}
func errTest( name string)(err error){
    
    
	defer func(){
    
    
		err := recover()
		if err != nil{
    
    
			fmt.Println("error Test err=",err)
		}
	}()
	if name == "zhangsan"{
    
    
		return nil
	}else{
    
    
		return errors.New("参数不合法")
	}
}

Guess you like

Origin blog.csdn.net/zhangxm_qz/article/details/114399427