函数的定义和调用
package main
import "fmt"
// 函数的定义
// func 函数名(参数)(返回值){
// 函数体
// }
// 函数定义
func add(a int, b int) (ret int) {
return a + b
}
func main() {
// 函数的调用
result := add(1, 1)
fmt.Println(result) //2
}
- 函数名:由字母、数字、下划线组成。但函数名的第一个字母不能是数字。在同一个包内,函数名也不能重复。
- 参数:参数由参数变量和参数变量类型组成,多个参数之间使用逗号分隔。
- 返回值:返回值由返回值变量和其变量类型组成,也可以只写返回值类型,多个返回值必须使用()分隔,并用逗号分隔。
- 函数体:实现指定功能的代码块。
参数类型简写
函数的参数中如果相邻变量的类型相同,则可以省略
func add(a , b int) int {
return a + b
}
可变参数
可变参数是指函数的参数数量不固定。Go语言中的可变参数通过在参数名后加...来标识。需要注意的是,可变参数通常要作为函数的最后一个参数。
package main
import "fmt"
// 可变参数
func add(a ...int) (ret int) {
// a是一个切片
sum := 0
for _, v := range a {
sum += v
}
return sum
}
func main() {
fmt.Println(add(1, 1)) //2
fmt.Println(add(1, 1, 1)) //3
fmt.Println(add(1, 1, 1, 1)) //4
}
返回值
Go语言中支持多返回值,函数如果有多个返回值必须使用()将所有返回值包裹起来。
package main
import "fmt"
// 多返回值
func add(a int, b string) (int, bool) {
return 1, true
}
func main() {
n, flag := add(1, "11")
fmt.Println(n, flag)
}
返回值的命名
函数定义时,可以给函数返回值命名,并在函数体中直接使用这些变量
package main
import "fmt"
// 多返回值 返回值命名
func add(a int, b string) (num int, flag bool) {
num = 123
flag = false
return
}
func main() {
num, flag := add(1, "11")
fmt.Println(num, flag) //123,false
}
函数进阶
变量作用域
全局变量
全局变量是定义在函数外部的变量,它在程序整个运行周期内有效。在函数中可以访问到全局变量。
package main
import "fmt"
// 定义全局变量
var name = "jack"
func showName() {
fmt.Println(name)
}
func main() {
showName() // jack
}
局部变量
函数内定义的变量无法在函数外使用。
package main
import "fmt"
func showName() {
// 只有函数内部才能使用这种定义变量的方法
name := "jack"
fmt.Println(name)
}
func main() {
showName() // jack
// 报错 不能再函数外使用函数内定义的变量
// fmt.Println(name)
}
语句块中的局部变量
package main
import "fmt"
func showName() {
name := "jack"
flag := true
if flag {
age := 12
fmt.Println(age) //12
fmt.Println(name) //jack
}
// 报错不能再函数外使用函数内定义的变量
// fmt.Println(age)
fmt.Println(name) //jack
}
func main() {
showName() // jack
// 报错 不能再函数外使用函数内定义的变量
// fmt.Println(name)
}
函数类型和变量
定义函数类型
使用
type
关键字来定义一个函数类型。
package main
import "fmt"
// 定义函数类型
type calculation func(int, int) int
func add(x, y int) int {
return x + y
}
func main() {
// 定义函数类型变量
var c calculation
c = add
result := c(1, 2)
fmt.Println(result) //3
}
函数变量类型
package main
import "fmt"
// 定义函数类型
type calculation func(int, int) int
func add(x, y int) int {
return x + y
}
func main() {
// 定义函数类型变量
var c calculation
c = add
result := c(1, 2)
fmt.Println(result) //3
fmt.Printf("%T\n",c) //main.calculation
}
高阶函数
函数作为参数
package main
import "fmt"
func add(x, y int) int {
return x + y
}
func calc(x, y int, op func(int, int) int) int {
return op(x, y)
}
func main() {
fn := calc(1, 2, add)
fmt.Println(fn) //3
}
函数作为返回值
package main
import "fmt"
func add(x, y int) int {
return x + y
}
func sub(x, y int) int {
return x - y
}
func do(s string) (func(int, int) int, error) {
switch s {
case "+":
return add, nil
case "-":
return sub, nil
default:
return nil, nil
}
}
func main() {
fn, error := do("+")
fmt.Println(fn(1, 2)) //3
fmt.Println(error) //<nil>
fn2, error2 := do("-")
fmt.Println(fn2(1, 2)) //-1
fmt.Println(error2) // <nil>
}
匿名函数和闭包
匿名函数
在Go语言中,函数内部只能定义匿名函数
package main
import "fmt"
func main() {
// func(参数)(返回值){
// 函数体
// }
add := func(x, y int) int {
return x + y
}
fmt.Println(add(1, 1)) //2
}
闭包
闭包指的是一个函数和与其相关的引用环境组合而成的实体。
package main
import "fmt"
// 闭包
func adder() func(int) int {
var x int
return func(y int) int {
x += y
return x
}
}
func main() {
f := adder()
fmt.Println(f(10)) //10
fmt.Println(f(20)) //30
fmt.Println(f(30)) //60
}
defer函数
Go
语言中的defer
语句会将其后面跟随的语句进行延时处理。在defer
归属的函数即将返回时,将延迟处理的语句按defer
定义的逆序进行执行。
package main
import "fmt"
func main() {
fmt.Println("start")
defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
fmt.Println("end")
// start
// end
// 3
// 2
// 1
}