函数定义
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函数。。。")
}