Go语言函数
一、基本介绍
为完成某一功能的程序语句的集合,称为函数,分为自定义函数和系统函数。
二、基本语法
func 函数名 (形参列表) (返回值类型列表) {
执行语法...
return 返回值列表
}
例子:
// 函数返回两个数的最大值
func max(num1 int, num2 int) int {
var result int
if num1 > num2 {
result = num1
} else {
result = num2
}
return result
}
三、函数的调用
package main
import (
"fmt"
)
func main() {
var num1 int = 300
var num2 int = 200
var result int
// 调用函数并返回最大值
result = max(num1, num2)
fmt.Printf("最大值为%d\n", result)
}
// 函数返回两个数的最大值
func max(num1 int, num2 int) int {
var result int
if num1 > num2 {
result = num1
} else {
result = num2
}
return result
}
输出结果:
最大值为300
四、函数的调用机制
通过一个例子来分析:编写一个函数传入一个值,并将值加一
package main
import "fmt"
func main() {
var a int = 10
test(a)
fmt.Println("main() a=",a)
}
func test (a int) {
a += 1
fmt.Println("test() a =",a)
}
输出结果:
test() a = 11
main() a= 10
示意图如下:
说明:
- 在调用一个函数时,会给该函数分配一个新的空间,编译器会通过自身处理让这个空间和其他的栈空间区分开来
- 在每个函数对应的栈中,数据空间是独立的,不会混淆
- 当一个函数调用完毕(执行完毕)后,程序会销毁这个函数对应的栈空间
五、函数参数的传递方式
- 值传递(值类型:基本数据类型int系列,float系列,bool,string,数组,结构体struc)
- 引用传递(引用类型:指针,切片slice,map,interface,管道chan等都是引用类型)
其实不管是值传递还是引用传递,传递给函数的都是变量的副本,不同的是,值传递的是值的拷贝,引用传递的是地址的拷贝,一般来说地址拷贝效率高,因为数据量小,而值拷贝取决于拷贝数据的大小,数据越大,效率越低、
六、函数返回多个值
Go 函数可以返回多个值,例如:
package main
import (
"fmt"
)
func main() {
var a string = "帅"
var b string = "哥"
fmt.Printf("交换前a,b:%v%v\n", a, b)
a, b = swap(a, b)
fmt.Printf("交换后a,b:%v%v\n", a, b)
}
// 函数交换值
func swap(str1 string, str2 string) (string, string) {
return str2, str1
}
输出结果:
交换前a,b:帅哥
交换后a,b:哥帅
七、递归调用
例子:使用递归调用的方式,求出前10个斐波那契数1,1,2,3,5,8,13...
package main
import (
"fmt"
)
func main() {
for i := 1; i <= 10; i++ {
res := fbn(i)
fmt.Printf("%d ", res)
}
}
func fbn(n int) int {
if n == 1 || n == 2 {
return 1
} else {
return fbn(n-1) + fbn(n-2)
}
}
输出结果:
1 1 2 3 5 8 13 21 34 55
八、注意细节
- 函数的形参列表可以是多个,返回值列表也可以是多个
- 形参列表和返回值列表的数据类型可以是值类型和引用类型
- 函数的命名遵循标识符命名规范,首字母不能是数字,首字母大写该函数可以被本包文件和其他包文件使用,类似public,首字母小写,只能被本包文件使用,其他包文件不能使用,类似private
- 函数中的变量时局部的,函数外不生效。
- 基本类型和数组默认都是值传递,即进行值拷贝,在函数内修改,不会影响到原来的值。
- 如果希望函数内的变量能修改函数外的变量,可以传入变量的地址&,函数内以指针的方式操作变量,从效果上类似引用。
- go函数不支持重载
- 在Go中,函数也是一种数据类型,可以赋值给一个变量,则该变量就是一个函数类型变量了。通过该变量可以对函数调用。
- 函数既然是一种数据类型,因此在Go中,函数可以作为形参,并且调用。
- 为了简化数据类型定义,Go支持自定义数据类型
基本语法:
type 自定义数据类型名 数据类型 //相当于起了一个别名
例如:
type myfunc func(int,int) int
- 支持函数返回值命名
例如:
func cal(a int, b int) (sum int, sub int) {
sum = a + b
sub = a - b
return
}
- 如果返回多个值时,在接受时,希望忽略某个返回值,则使用 _ 符号表示占位忽略。
- Go支持可变参数
package main
import (
"fmt"
)
func main() {
res := sum(10, 20, 30)
fmt.Printf("res=%d\n", res)
}
func sum(a int, args ...int) int {
sum := a
for i := 0; i < len(args); i++ {
sum += args[i]
}
return sum
}
输出结果:
res=60
说明:
- args是slice,通过args[index]可以访问各个值。
- 如果一个函数的形参列表中有可变参数,则可变参数需要放在形参最后。
- 如果返回一个值时,返回值类型列表,可以不写()。