天天看点

GO语言之函数

函数定义

Go 语言函数定义格式如下:

func function_name( [parameter list] ) [return_types] {
   函数体
}
           
func 函数名(形式参数列表)(返回值列表){
    函数体
}
           

函数定义解析:

func:函数由 func 开始声明

function_name:函数名称,函数名和参数列表一起构成了函数签名。

parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。

return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。

函数体:函数定义的代码集合。

特别注意:

1、如果一个函数在声明时,包含返回值列表,那么该函数必须以 return 语句结尾,除非函数明显无法运行到结尾处,例如函数在结尾时调用了 panic 异常或函数中存在无限循环。

多个参数如果类型相同,可以合并写法,单个返回值可以不写括号

eg:

func hypot(x, y float64) float64 {
    return math.Sqrt(x*x + y*y)
}
fmt.Println(hypot(3,4)) // "5"
           

x 和 y 是形参名,3 和 4 是调用时的传入的实数,函数返回了一个 float64 类型的值,返回值也可以像形式参数一样被命名,必须以

return

结尾。在这种情况下,每个返回值被声明成一个局部变量,并根据该返回值的类型,将其初始化为 0。

函数之变量的作用域

1、全局变量可在局部函数中直接使用

var a string ="123"

func main() {
	 test()
}
func test() {

	fmt.Println("变量",a)
}
           

2、如果自己局部函数存在此变量,将用自己局部函数的变量值

var a string ="123"
func main() {
	 test()
	 fmt.Println(a)
}
func test() {
	a := "456"

	fmt.Println("变量",a)
}
           

运行结果:

变量 456 123

3、全局不能访问局部函数的变量,除非使用return返回

func main(){
     J()
     fmt.Println(a)  //这么写是错误的,识别不到局部函数的变量
	}
    func J()  {
	  a := 123
}
           

return返回方式可以使用局部变量

func main() {
	 b := test()  //需要赋值
	 fmt.Println(b)
}
func test() (a string){
	a = "456"
	return
}
           

4、语句中的变量是不能被全局使用的

func main(){
		for i :=0 ; i<10;i++  {
			fmt.Println(i) //语句中这么写没问题
		}
		fmt.Println(i)  //这里这么写会报错,找不到变量i
	}
           

其他用法

1、普通写法返回值函数

package main          

import "fmt"    //引入fmt程序包

func main() {
	a := 100
	b := 200
	c := 300
	sum1,sum2,sum3 := Add(a,b,c)    //这里调用了Add函数,并必须赋予三个变量,因为Add函数返回3个值,要不然会报错,其中a对应Add函数的a1,b对应a2,c对应a3;sum1对应的suma,sum2对应的是sumb,sum3对应的是sumc
	fmt.Println(sum1,sum2,sum3)
}

func Add(a1,a2,a3 int)(int,int,int){    //Add函数名称自定义,但必须与主函数main调用的名称一致
//声明了3个形参a1、a2、a3为int类型;三个返回值都为int类型
	var suma int
	var sumb int
	var sumc int
	suma = a1 + a2
	sumb = a2 + a3
	sumc = a3 + a1
	return suma,sumb,sumc      //返回3个值,分别对应函数头三个int类型的值

}
           

300 500 400

2、简写返回值函数

命名返回值写法,使用这种形式,返回值的名称已经在声明中定义,不需要在函数体内定义,return后面也可以不写上返回值的名称,默认会返回函数声明中那几个命名的返回值

package main

import "fmt"

func main() {
	sum1,sum2,sum3 := Add(100,200,300)    //这里调用了Add函数,并必须赋予三个变量,因为Add函数返回3个值,要不然会报错
	fmt.Println(sum1,sum2,sum3) //先把100,200,300传入进去,分别对应a1,a2,a3,Add函数进行计算后,返回suma、sumb、sumc,对应sum1、sum2、sum3
}

func Add(a1,a2,a3 int)(suma int, sumb int,sumc int){  //直接声明返回值名称为suma、sumb、sumc,函数体内就不需要var 或者 :=声明变量了

	suma = a1 + a2
	sumb = a2 + a3
	sumc = a3 + a1
	return         //函数返回值已定义,直接写return即可

}

           

300 500 400

3、可变函数写法,可变函数其实是一个切片

func intSum(a ...int) int {
	ret := 0        //一次性声明,后面的ret值与它无关。不参加遍历
	for _, arg := range a {
		ret = ret + arg  //ret=0+10--> ,ret=10, ret=10+20,ret=30,遍历结束,返回30
	}
	fmt.Printf("intSum类型是:%T\n", a)//打印可变参数的类型
	return ret
}
func main(){
	r1 := intSum(10,20)
	fmt.Println(r1)
}

           

intSum类型是:[]int 30

3、固定参数和可变参数结合使用

func intSum(a int,b...int) int {
	ret := a        //一次性声明,后面的ret值与它无关。不参加遍历
	for _, arg := range b {
		ret = ret + arg  //ret=0+10--> ,ret=10, ret=10+20,ret=30,遍历结束,返回30

	}
	fmt.Printf("intSum类型是:%T\n", b)
	return ret
	}
func main(){

	r2 := intSum(10,20,30)

	fmt.Println(r2)
	}
           
//defer函数在语句的最后执行,并按照倒序执行defer语句
//一般用于处理资源释放、文件关闭、解锁及记录时间等
package main
import "fmt"
func main() {
    defer fmt.Println("789")
	defer fmt.Println("456")
	fmt.Println("123")	
}
           
package main

import "fmt"

func main() {
	A()                    //在go语言中最简单的调用这么写就可以,main主函数调用A函数
	
}
func A(){
	fmt.Println("开始执行A函数。。。")
	B()                    //A函数调用B函数
	fmt.Println("B函数执行结束")  //B函数执行完毕,继续执行
	fmt.Println("A函数执行结束")

}
func B(){
	fmt.Println("开始执行B函数。。。")

}