GO语言函数
- GO语言是由函数组成的
- 没有返回值没有形参的函数
- 有返回值没有形参的函数
- 没有返回值有形参的函数
- 有返回值有形参的函数
- 函数格式
func 函数名称 (形参列表)(返回值列表){
函数语句
}
- 注意点:
- GO语言中函数不用声明可以直接使用
- 如果只有一个返回值,返回值列表的" () "可以省略
package main
import "fmt"
func main() {
res :=sum(10,20)
fmt.Println(res) // 30
}
func sum(a,b int) int { // 返回值列表省略
res := a + b
return res
}
- GO语言函数如果有返回值的话,可以在返回值列表中定义变量,可以在函数中直接使用变量, return 后面就可以不用写任何内容了 系统默认会将返回值列表定义的变量返回
package main
import "fmt"
func main() {
res :=sum(10,20)
fmt.Println(res) // 30
}
func sum(a,b int)(resule int) {
resule = a + b
return
}
- GO语言中可以有多个返回值
- 如果有多个返回值, 但是只想使用其中一个的话 可以利用 " _ "来忽略掉不需要的那个值
package main
import "fmt"
func main() {
res,_ :=getNum()
fmt.Println(res) // 666
}
func getNum()(a,b int){
a = 666
b = 888
return
}
- 如果多个返回值类型和形参类型一样 只需要在最后一个变量后面写上数据类型就行
- 如果想在函数内部修改外界传入的实参, 和C语言的函数一样必须传入指针
package main
import "fmt"
func main() {
a := 23
change(&a)
fmt.Println(a)
}
func change(a *int){
*a = 999
}
匿名函数
-
概念
匿名函数就是没有名字的函数
package main
import "fmt"
func main() {
//定义一个匿名函数立即调用
func(){
fmt.Println("匿名函数")
}()
}
- 注意点
- 匿名函数定义完,必须马上被调用,否则编译器会报错
- 可以将一个匿名函数保存到变量里面
package main
import "fmt"
func main() {
//定义一个函数变量 保存 匿名函数
var fn func() // fn 函数变量名称 func() 函数数据类型
fn = func(){
fmt.Println("变量保存匿名函数格式1")
}
fn()
}
package main
import "fmt"
func main() {
// 第二种格式
fn := func() {
fmt.Println("变量保存匿名函数格式2")
}
fn() // 调用
}
- 所以GO语言可以用函数类型来定义变量(类似C语言中指向函数的指针变量)
- 定义函数变量的格式和定义变量的格式一样适用
- 应用场景
- 如果一个函数只会被调用一次的时候就会使用匿名函数
- 或者作为函数的参数和返回值传入
- 匿名函数作为参数
package main
import "fmt"
func main() {
var fn func(int,int)int = func(a int,b int)int {
return a + b
}
fmt.Printf("%T",fn) // func(int, int) int
res1 := calculater(10,20,fn)
res2 := calculater(10,20, func(a int, b int) int {
res:= a + b
return res
})
fmt.Println("res1 = ",res1) // 30
fmt.Println("res1 = ",res2) // 30
}
func calculater(a,b int ,method func(int,int) int ) (int){
res:= method(a,b)
return res
}
-
图解
1.png - 匿名函数作为参数2
package main
import "fmt"
func main() {
//匿名函数做为参数
var fn func()
fn = func() {
fmt.Println("匿名函数")
}
fmt.Printf("fn = %p\n",fn)
test(fn)
//或者可以转化为
test( func() {
fmt.Println("匿名函数")
} )
}
func test(method func()){
fmt.Printf("%p\n",method)
method()
}
-
图解
微信图片_20180922153055.png
- 匿名函数作为返回值
package main
import "fmt"
func main() {
var fn func()
fn = test()
fn()
}
func test()func() {
return func() {
fmt.Println("匿名函数")
}
}
-
画图简解
微信图片_20180922160045.png -
匿名函数作为返回值
package main
import "fmt"
func main() {
var fn func(int,int)int // 创建相同的返回值类型 func(int,int)int 就可以接收他
fn = test() // 接收test 函数的返回值
res := fn(10,30) // 调用
fmt.Println(res) // res = 40
}
func test()func(int,int)int { //返回值类型为 func(int,int)int
return func(a int,b int)int {
return a + b
}
}
- 匿名函数练习
package main
import "fmt"
func main() {
work(func() {
fmt.Println("开会")
fmt.Println("写报告")
fmt.Println("提交方案")
fmt.Println("写代码")
})
}
// 每个人工作的一天
func work(method func()){
// 上班前
func(){
fmt.Println("起床")
fmt.Println("刷牙")
fmt.Println("吃早饭")
fmt.Println("上班")
fmt.Println("打卡")
}()
// 上班内容
method()
//下班
func (){
fmt.Println("下班")
fmt.Println("打卡")
fmt.Println("回家")
}()
}
-
图解
微信图片_20180922160045.png
闭包
-
概念
闭包就是一个特殊的匿名函数, 只要匿名函数中用到了外界的变量 那么我们就吧匿名函数叫做闭包 -
注意点
只要闭包还在使用外界的变量,那么外界的变量就会一直存在 - 代码演示
package main
import "fmt"
func main() {
num := 10
a := func() {
num++ /这里的num 就是匿名函数外界的变量 所以这就是一个闭包
fmt.Println(num)
}
a() //11
a() //12
a() //13
}
package main
import "fmt"
func main() {
fn:= add() //因为add返回的是一个闭包 所以fn 就是闭包 所以x会一直在
fn() //2
fn() //3
fn() //4
}
func add()func(){
x := 1
return func() {
x++
fmt.Println(x)
}
}
defer 语句
-
格式
defer 语句
-
作用
- defer就是用来延迟执行,会在所属函数执行完毕后再执行defer语句
-
应用场景
常用于 资源释放,解锁,错误处理等等 -
注意点
如果在一个函数里面定义了多个defer语句,那么会遵守先进后执行,后进先执行的,规律
package main
import "fmt"
func main() {
defer fmt.Println("第一条语句") / 第四个执行
defer fmt.Println("第二条语句") / 第三个执行
defer fmt.Println("第三条语句") / 第二个执行
defer fmt.Println("第四条语句") / 第一个执行
}
init 函数
- 在Go语言中保留了两个函数,一个是main函数 一个就是init函数, 他们都是由系统调用的
- 格式
func init( ){ }
-
init函数的作用
对当前文件进行初始化 -
Go语言的调用顺序
main包--->常量--->全局变量--->init函数--->main函数--->逻辑代码--->退出程序
-
注意点
- main函数只能在main包里(package main) , 并且一个程序只能有一个main
- init函数每个包都可以有
- 并且每个包可以有多个,但是推荐每个包只写写一个
网友评论