声明语法
func 函数名 (参数列表) [(返回值列表)] {}
Golang函数特点
a. 不支持重载,一个包不能有两个名字一样的函数
b. 函数是一等公民,函数也是一种类型,一个函数可以赋值给变量
c. 匿名函数
d. 多返回值
函数的参数传递方式
值传递
引用传递
注意1:
无论是值传递,还是引用传递,传递给函数的都是变量的副本,
不过,值传递是值的拷贝。引用传递是地址的拷贝,一般来说,地址
拷贝更为高效。而值拷贝取决于拷贝的对象大小,对象越大,则性能
越低。
注意2:
map、slice、chan、指针、interface默认以引用的方式传递
/*
package main import "fmt" func modify(a int) {
a = 100
} func main(){
a := 8
fmt.Println(a)
modify(a)
fmt.Println(a)
}
*/
// 修改上面的程序, 使其正确 package main import "fmt" func modify(a *int) {
*a =
} func main(){
a :=
fmt.Println(a)
modify(&a)
fmt.Println(a)
}
练习 13
命名返回值的名字
func add(a, b int) (c int) {
c = a + b
return
}
_标识符, 用来忽略返回值
func calc(a, b int) (sum int, avg int) {
sum = a + b
avg = (a +b)/
return
}
func main() {
sum, _ := calc(, )
}
可变参数
func add(arg…int) int { // 0个或多个参数 }
func add(i int, arg…int) int { // 1个或多个参数 }
func add(i int, j int, arg…int) int { // 2个或多个参数 }
注意:
其中arg是一个slice,我们可以通过arg[index]依次访问所有参数
通过len(arg)来判断传递参数的个数
// 写一个函数add, 支持一个或多个int相加, 并返回相加结果 package main import "fmt" func add(x int, arg...int) int{
var sum int = x
for i := ; i < len(arg); i++ {
sum += arg[i]
}
return sum
} func main(){
res := add(, )
fmt.Println(res)
}
练习14
// 写一个函数concat, 支持一个或者多个string相拼接, 并返回结果 package main import "fmt" func concat(str string, arg...string)(res string){
res = str
for i := ; i < len(arg); i++ {
res += arg[i]
}
return
} func main(){
res := concat("plm", "asd")
fmt.Println(res)
}
练习 15
defer的用途
. 当函数返回时,执行defer语句。因此,可以用来做资源清理
. 多个defer语句,按 先进后出 的方式执行
. defer语句中的变量,在defer声明时就决定了
应用:
1. 关闭文件句柄
func read(){
file := open(filename)
defer file.Close() //文件操作 }
2. 锁资源释放
func read() {
mc.Lock()
defer mc.Unlock()
//其他操作
}
3. 数据库连接释放
func read() {
conn := openDatabase()
defer conn.Close()
//其他操作
}