1.变量作用域
1.1全局变量
var num = 10 //全局变量
func main() {
fmt.Println(num)
}
1.2局部变量
如果局部变量和全局变量重名,优先访问局部变量
var num = 10 //局部变量
func main() {
num :=15
fmt.Println(num)
}
2.函数类型与变量
//定义函数类型
type calc func(int,int) int
func add(x,y int) int {
return x+y
}
func sub(x, y int) int {
return x-y
}
//函数类型变量
func main() {
var c calc
c = add
fmt.Printf("%T\n",c) //main.calc
fmt.Println(c(1,2))
f := add
fmt.Printf("%T\n",f) //func(int, int) int
fmt.Println(f(10,20))
}
3.高阶函数
3.1函数作为参数
func add(x, y int) int {
return x+y
}
func sub(x, y int) int {
return x-y
}
func calc(x,y int,op func(int,int) int) int {
return op(x,y)
}
func main() {
sum := calc(1, 2, add)
sub := calc(10, 5, sub)
fmt.Println(sum,sub)
}
4.匿名函数和闭包
4.1匿名函数
add := func(x, y int){
fmt.Println(x+y)
}
add(10,20) //30
func(x,y int){
fmt.Println(x+y)
}(10,20) //30
4.2闭包
闭包=函数+引用环境
func adder() func(int) int {
var x int
return func(y int) int {
x+=y
return x
}
}
func main() {
var f = adder()
fmt.Println(f(10))
f1 := adder()
fmt.Println(f1(50))
}
func adder(x int) func(int) int {
return func(y int) int {
x+=y
return x
}
}
func main() {
var f = adder(10)
fmt.Println(f(10))
f1 := adder(50)
fmt.Println(f1(50))
}
func calc(num int) (func(int) int,func(int) int) {
add:= func(i int) int{
num+=i
return num
}
sub:= func(i int) int{
num-=i
return num
}
return add,sub
}
func main() {
f1, f2 := calc(10)
fmt.Println(f1(10),f2(10))
}
5.defer语句
Go语言中的defer语句会将其后面跟随的语句进行延迟处理。将延迟处理的语句按defer定义的逆序进行执行,也就是说,先被defer的语句最后被执行,最后被defer的语句,最先被执行。
fmt.Println("start")
defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
fmt.Println("end")
由于defer语句延迟调用的特性,所以defer语句能非常方便的处理资源释放问题
start
end
3
2
1
经典案例
func f1() int {
x := 5
defer func() {
x++
}()
return x
}
func f2() (x int) {
defer func() {
x++
}()
return 5
}
func f3() (y int) {
x := 5
defer func() {
x++
}()
return x
}
func f4() (x int) {
defer func(x int) {
x++
}(x)
return 5
}
func main() {
fmt.Println(f1())
fmt.Println(f2())
fmt.Println(f3())
fmt.Println(f4())
}
6.内置函数
内置函数 | 介绍 |
---|---|
close | 主要用来关闭channel |
len | 用来求长度,比如string、array、slice、map、channel |
new | 用来分配内存,主要用来分配值类型,比如int、struct。返回的是指针 |
make | 用来分配内存,主要用来分配引用类型,比如chan、map、slice |
append | 用来追加元素到数组、slice中 |
panic和recover | 用来做错误处理 |
7.panic/recover
panic可以在任何地方引发,但recover只有在defer调用的函数中有效
func f1() {
fmt.Println("f1")
}
func f2() {
//fmt.Println("f2")
panic("panic in f2")
}
func f3() {
fmt.Println("f3")
}
func main() {
f1()
f2()
f3()
}
可以通过recover将程序恢复回来,继续往后执行
func f1() {
fmt.Println("f1")
}
func f2() {
defer func() {
err := recover()
//如果程序出出现了panic错误,可以通过recover恢复过来
if err !=nil{
fmt.Println("recover in f2")
}
}()
panic("panic in B")
}
func f3() {
fmt.Println("f3")
}
func main() {
f1()
f2()
f3()
}
- recover()必须搭配defer使用。
- defer一定要在可能引发panic的语句之前定义