自定义类型
package main
import (
"fmt"
)
type calc func(int, int) int //表示定义一个calc的类型
type myInt int
func add(x, y int) int {
return x + y
}
func main() {
var c calc
c = add
fmt.Printf("c的类型:%T\n", c) //c的类型:main.calc
fmt.Println(c(10, 5)) //15
f := add
fmt.Printf("f的类型:%T\n", f) //f的类型:func(int, int) int
var a int
var b myInt
fmt.Printf("%T\n", a) //int
fmt.Printf("%T\n", b) //main.myInt
}
将函数作为另一函数的参数
package main
import (
"fmt"
)
func add(x, y int) int {
return x + y
}
type calcType func(int, int) int
func calc(x, y int, cb calcType) int {
return cb(x, y)
}
func main() {
sum := calc(10, 5, add)
fmt.Println(sum) //15
//匿名函数
j := calc(3, 4, func(x, y int) int {
return x * y
})
fmt.Println(j) //12
}
函数作为返回值
package main
import (
"fmt"
)
func add(x, y int) int {
return x + y
}
type calcType func(int, int) int
func calc(x, y int, cb calcType) int {
return cb(x, y)
}
func do(o string) calcType {
switch o {
case "+":
return add
case "*":
return func(x, y int) int {
return x * y
}
default:
return nil
}
}
func main() {
var a = do("+")
fmt.Println(a(1, 9)) //10
}
匿名自执行函数接收参数
func main() {
func(x, y int) {
fmt.Println(x + y)
}(10, 20) //30
}
函数递归:自己调用自己
func fn1(n int) {
if n > 0 {
fmt.Println(n)
n--
fn1(n)
}
}
//递归实现1~100的和
func fn2(n int) int {
if n > 1 {
return n + fn2(n-1)
} else {
return 1
}
}
闭包
闭包可以理解成“定义在一个函数内部的函数”。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
全局变量:常驻内存,污染全局
局部变量:不常驻内存,不污染全局
闭包:常驻内存,不污染全局
package main
import (
"fmt"
)
//写法:函数里面嵌套一个函数,最后返回里面的函数
func adder1() func() int {
var i = 10
return func() int {
return i + 1
}
}
func adder2() func(y int) int {
var i = 10
return func(y int) int {
i += y
return i
}
}
func main() {
var fn1 = adder1() //表示执行方法
fmt.Println(fn1()) //11
fmt.Println(fn1()) //11
fmt.Println(fn1()) //11
var fn2 = adder2()
fmt.Println(fn2(1)) //11
fmt.Println(fn2(1)) //12
fmt.Println(fn2(1)) //13
}
defer:延迟执行,之后逆序执行
提示:defer注册要延迟执行的函数时,该函数所有参数都需要确定其值
func main() {
fmt.Println("开始")
defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
fmt.Println("结束")
}
/*
开始
结束
3
2
1
*/
package main
import (
"fmt"
)
//匿名函数
func f1() int {
var a int
defer func() {
a++
}()
return a
}
//命名函数
func f2() (a int) {
defer func() {
a++
}()
return a
}
func main() {
fmt.Println(f1()) //0
fmt.Println(f2()) //1
}
recover defer配合异常处理
Go(Go1.12)没有异常机制,可使用 panic / recover 模式来处理错误
panic 可以在任何地方引发,但 recover 只有在 defer 调用的函数中有效
package main
import (
"fmt"
)
func fn1() {
fmt.Println("fn1")
}
func fn2() {
defer func() {
err := recover()
if err != nil {
fmt.Println("有错误", err)
}
}()
panic("抛出一个错误")
}
func main() {
fn1()
fn2()
fmt.Println("结束")
}
/*
fn1
有错误 抛出一个错误
结束
*/
defer、panic、recover 配合使用:自定义错误
一个发送邮件的程序
package main
import (
"errors"
"fmt"
)
//defer、panic、recover
func readFile(fileName string) error {
if fileName == "main.go" {
return nil
} else {
return errors.New("读取文件失败")
}
}
func myFn() {
defer func() {
e := recover()
if e != nil {
fmt.Println("错误,给管理员发送邮件")
}
}()
err := readFile("xxx.go")
if err != nil {
panic(err)
}
}
func main() {
myFn()
fmt.Println("程序向下执行~~~")
}
/*
错误,给管理员发送邮件
程序向下执行~~~
*/
网友评论