函数
原创大约 3 分钟
package main
import (
"fmt"
"sync"
)
/*
go中的函数全部都是“值传递”
函数可以返回多个值
1. 函数返回多个值,返回值类型可以不同
2. 函数返回多个值,返回值类型可以相同
3. 函数返回多个值,返回值类型可以相同,但是顺序可以不同
4. 函数返回多个值,返回值类型可以相同,但是顺序可以不同,但是不能省略
*/
func add1(a, b int) int {
a = 3
fmt.Println(a)
return a + b
}
// 因为已经定义了返回值名称,所以return后面可以省略变量名
func add2(a, b int) (sum int, err error) {
sum = a + b
return
}
// 变长参数
func add4(items ...int) (sum int) {
for _, v := range items {
sum += v
}
return
}
func add5(desc string, items ...int) (sum int) {
fmt.Printf("%s: ", desc)
for _, v := range items {
sum += v
}
return
}
// 一个计算器函数
func calc1(desc string, items ...int) func() {
switch desc {
case "sum":
//for _, v := range items {
// sum += v
//}
return func() {
fmt.Println("这是加法")
}
case "sub":
//for i, v := range items {
// if i == 0 {
// sum = v
// } else {
// sum -= v
// }
//}
return func() {
fmt.Println("这是减法")
}
default:
return func() {
fmt.Println("这是默认")
}
}
}
// 参数和返回值都是函数
func calc2(desc string, myfunc func(items ...int) int) func() {
switch desc {
case "+":
fmt.Println(myfunc(1, 2, 3))
return func() {
fmt.Println("加法运算")
}
case "-":
fmt.Println(myfunc(1, 2))
return func() {
fmt.Println("减法运算")
}
default:
fmt.Println(myfunc())
return func() {
fmt.Println("默认运算")
}
}
}
// 闭包函数
func autoIncrement() func() int {
local := 0
// 在一个函数中访问另一个函数的局部变量
return func() int {
local += 1
return local
}
}
func deferReturn() (ret int) {
// defer后面也可以自定义函数
// 在return之前执行
defer func() {
ret++
}()
// 由于在return之前调用,因此ret的值是11
return 10
}
func main() {
// 函数
// go支持普通函数、匿名函数和闭包
/*
go中函数是一等公民
1. 函数本身可以当作变量
2. 函数可以满足接口
3. 匿名函数和闭包
*/
a := 1
b := 2
fmt.Println(add1(a, b))
// 因为a是传值引用,所以本身的值不会受到影响
fmt.Println(a)
fmt.Println("====================")
r1, _ := add2(1, 2)
fmt.Println(r1)
fmt.Println("====================")
// 函数可变参数
fmt.Println(add5("累加求和"))
fmt.Println(add5("累加求和", 1))
fmt.Println(add5("累加求和", 1, 2))
fmt.Println("====================")
// 函数的一等公民特性
// 直接将函数“赋值”给了一个变量,让这个变量也具有了函数的特性
test := add5
// 变量可以像函数那样使用
fmt.Println(test("累加求和"))
fmt.Println("====================")
// 这样是无法显示结果的
calc1("22")
// 因为函数返回的是一个函数,所以需要调用这个函数
calc1("22")()
fmt.Println("====================")
calc2("+", add4)()
// 匿名函数
f := func(items ...int) int {
sum := 0
for _, v := range items {
sum += v
}
return sum
}
fmt.Println(f(1, 2, 3))
fmt.Println("====================")
/*
函数的闭包:在一个(匿名的)内部函数中,引用了它所在的外部函数中的变量,就叫闭包
*/
// 通过返回匿名函数,实现动态的自增逻辑
nextFunc := autoIncrement()
for i := 0; i < 5; i++ {
fmt.Println(nextFunc())
}
// 再次调用则归零重新计算
nextFunc = autoIncrement()
// 函数的defer,相当于java中的finally
var lock sync.Mutex
lock.Lock()
// defer后面的代码一定会在函数的return之前执行
defer lock.Unlock()
// 演示多个defer的执行顺序:离return近的先执行,相当于执行“出栈”操作
defer fmt.Println("defer1")
defer fmt.Println("defer2")
defer fmt.Println("defer3")
fmt.Println("main")
ret := deferReturn()
fmt.Println(ret)
return
}
感谢支持
更多内容,请移步《超级个体》。