05 Funciones, paquetes y manejo de errores

función

Completar una determinada gramática de definición de conjunto de instrucciones de programa funcional

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

Código de muestra

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

}

Ejemplo de código de retorno de varios valores

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
	
}

punto importante

  1. En la transferencia de funciones, los tipos de datos básicos y las matrices son todas transferencias de valor por defecto, es decir, el valor se copia y la modificación en la función no afecta el valor original. Si desea que el cambio del valor en la función sea afectar el valor fuera de la función, puede pasar la dirección & num, función Manipular variables en forma de punteros
  2. Go no admite la sobrecarga de funciones
  3. Las funciones en Go también son un tipo que se puede asignar a variables, y las funciones se pueden llamar a través de variables
  4. Las funciones se pueden pasar a funciones como parámetros formales
  5. Admite nombrar el valor de retorno de la función, después de nombrar el retorno, no es necesario agregar un valor para devolver. Devuelve automáticamente la variable de valor de retorno declarada
  6. Las funciones Go admiten parámetros variables

paquete

Se utiliza para distinguir las variables de función con el mismo nombre, para administrar mejor el alcance de los archivos de código, controlar las variables de función, etc.
Cada carpeta en go es un paquete

punto importante

  1. Al empaquetar un archivo, el paquete corresponde a una carpeta, como package utils y package main en el ejemplo, que generalmente son iguales a la carpeta, generalmente en letras minúsculas.
  2. Cuando un archivo necesita usar funciones o variables de otros paquetes, primero debe importar la ruta correspondiente, como import go01 / utils en el ejemplo. Al importar el paquete, el compilador Go buscará automáticamente la ruta desde el src en GOPATH e importe el contenido.
  3. Si las variables de método en el paquete van a ser referenciadas por otros paquetes, la primera letra debe estar en mayúscula
  4. Utilice el método del nombre del paquete y el nombre de la función al llamar a otros contenidos del paquete
  5. Si el nombre del paquete es muy largo, se puede usar un alias al importar, como: import util “go01 / utils” Después de tomar el nombre del paquete, el nombre del paquete original no se puede usar.
  6. En el mismo paquete, no puede haber el mismo nombre de función o nombre de variable; de ​​lo contrario, se solicitará una definición repetida
  7. Si desea compilar en un archivo de programa ejecutable, debe declarar el paquete como principal. Esta es una especificación gramatical. Si está compilado en una biblioteca, el nombre del paquete se puede personalizar


Ejemplo de código go01 / main en main.go

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

en 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

}

función de inicio

Cada archivo puede contener una función de inicio, que se utiliza para el trabajo de inicialización antes de la ejecución. Antes de que la función se ejecute en la función principal, será llamado por el marco de tiempo de ejecución de Go.
ten cuidado

  1. Si un archivo contiene definiciones de variables globales al mismo tiempo, el orden de ejecución de la función init y la función principal es: definición de variable global -> función init -> función principal
  2. Si main.go llama a util.go y ambos incluyen el método init y las definiciones de variables globales, el orden de ejecución es: definición de variable uitl -> util init -> definición de variable principal -> método de inicio principal -> método principal principal

Ejemplo

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

Función anónima

Una función anónima es una función sin nombre. Si una función se usa solo una vez, considere usar una función anónima. La función anónima también se puede llamar varias veces en el
programa de ejemplo

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))
}

Cierre

Un cierre es una combinación de una función y su entorno de referencia relacionado como un todo.
Código de prueba

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
	}
}

Función diferir

En las funciones, los programadores a menudo necesitan crear recursos (conexiones de base de datos, bloqueos, etc.), y los recursos correspondientes deben liberarse después de que se ejecuta la función. Go proporciona un mecanismo de retardo diferido para lograr esto. Más conveniente
prestar atención

  1. Cuando go se ejecuta para referirse, la instrucción después de aplazar no se ejecutará inmediatamente, pero la instrucción después de aplazar se presionará en una pila, y luego se ejecutará la siguiente instrucción
  2. Una vez que se ejecuta la función, las declaraciones se extraen secuencialmente de la pila de aplazamiento y se ejecutan.
  3. Cuando defer pone la declaración en la pila, también copia el valor relacionado en la pila. El cambio de la variable de tipo de valor en el método no afecta el valor en la pila

Código de muestra

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
}

Alcance variable

  1. El alcance de la variable definida en la función o el bloque de instrucciones es este bloque de instrucciones.
  2. La variable declarada fuera de la función es una variable global, el alcance es el paquete real, si la primera letra está en mayúscula, el alcance es el programa completo

Funciones de uso común

Funciones de cadena de uso común

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])
	}

}

Funciones de fecha y hora

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()
}

Funciones integradas
Golang proporciona algunas funciones para la conveniencia de la programación, que se pueden usar directamente, las llamamos funciones integradas.

  1. len: se usa para encontrar la longitud como: cadena, matriz, sector, mapa, canal
  2. nuevo: se usa para asignar memoria, se usa principalmente para asignar tipos de valor, como: int float32, struc devuelve un puntero
  3. make: se utiliza para asignar memoria, se utiliza principalmente para asignar tipos de referencia, como el segmento de mapa de canal
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)

}

Manejo de errores

De forma predeterminada, después de que ocurra un error, el programa se cerrará. Podemos capturar y procesar el error y configurar un recordatorio para el administrador (correo electrónico \ SMS)

  1. Golang persigue una introducción elegante, por lo que no es compatible con la declaración tradicional try catch.
  2. Mediante la recuperación de pánico diferido, el programa ejecutó una excepción de pánico.
  3. Golang admite errores personalizados,
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("参数不合法")
	}
}

Supongo que te gusta

Origin blog.csdn.net/zhangxm_qz/article/details/114399427
Recomendado
Clasificación