加入收藏 | 设为首页 | 会员中心 | 我要投稿 51站长网 (https://www.51zhanzhang.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

一篇文章带你了解Go语言基础之函数

发布时间:2021-11-03 13:34:47 所属栏目:语言 来源:互联网
导读:前言 Hey,大家好呀,我是星期八,上篇文章学了些基础:一篇文章带你了解Go语言基础之函数(上篇),这次咱们继续学习Go基础之函数进阶叭。 Go函数内存分配图 Go的函数内存分配,有点像堆分配,有点像,但是本质不是。 可以理解像堆内存一样,栈中保存的是堆的
前言 Hey,大家好呀,我是星期八,上篇文章学了些基础:一篇文章带你了解Go语言基础之函数(上篇),这次咱们继续学习Go基础之函数进阶叭。   Go函数内存分配图 Go的函数内存分配,有点像堆分配,有点像,但是本质不是。       可以理解像堆内存一样,栈中保存的是堆的地址。   验证 代码   package main    import "fmt"      func say() string {      return "ok"  }    func main() {      fmt.Printf("say栈上的内容:%pn",say)  }  结果     本质     函数的作用域 作用域这个问题,以前可能或多或少提过,再来复习一下叭。   全局变量 全局变量就是在所有函数外部定义的变量,程序不结束,变量就一直存在。   当然,任何函数都可以访问全局变量。   注:全局变量尽量全部用大写。   小试牛刀   package main    import "fmt"      var NAME = "张三"  func say() string {      fmt.Println(NAME)      return "ok"  }    func main() {      say()      fmt.Println(NAME)  }  结果:       上述可能会有个问题,全局变量,全局变量,大家共用一个,要是谁傻不拉几修改了不就完蛋了,整个程序都凉了。   var引发的问题   就像这样。   package main    import "fmt"    var NAME = "张三"    func say() string {      fmt.Println(NAME)      NAME = "李四"      return "ok"  }    func main() {      say()      fmt.Println(NAME)  }  结果:       这不就完犊子了吗???所以,一定要有解决办法。   使用const解决问题   解决办法:使用常量定义全局变量。   package main    import "fmt"    const NAME = "张三"    func say() string {      fmt.Println(NAME)      //NAME = "李四"//会报错:cannot assign to NAME      return "ok"  }    func main() {      say()      fmt.Println(NAME)    }  总结   在定义全局变量时,需要用const修饰,并且变量名全部大写。   局部变量 局部变量,局部变量就是在某个函数内定义的变量,只能在自己函数内使用。   更专业点,在{}内定义的,只能在{}内使用,for同理。   代码   package main    import (      "fmt"  )    func say() string {      var name = "张三"      fmt.Println(name)      return "ok"  }    func main() {      say()      //fmt.Println(name)//会报错:undefined: name      //for同理      for i := 0; i <= 1; i++ {          var c = "66"          fmt.Println(c) //66  }      //fmt.Println(c)//会报错:undefined: c  }  defer 在Go中,defer语句,可以理解为在return之前执行的一个语句。   如果函数没有return,会有一个默认的return,只是看不见而已。   一个defer 代码   package main    import "fmt"    func say() {      //defer尽量往前放      defer fmt.Println("我是666")      fmt.Println("你们都是最棒的")  }    func main() {      say()  }  执行结果       多个defer 代码   package main    import "fmt"    func say() {      //defer尽量往前放      defer fmt.Println(1)      defer fmt.Println(2)      defer fmt.Println(3)      fmt.Println("你们都是最棒的")  }    func main() {      say()  }  执行结果       可以发现,defer的执行结果是反着的。   结论:最先执行的defer,会最后执行,最后执行的defer,会最先执行,有点像栈,先进后出。   defer的作用 通常来说,defer会用在释放数据库连接,关闭文件等需要在函数结束时处理的操作。   这里暂时先不举例子。   panic和recover 这俩,可以理解为Python中的try和raise,因为在Go中,是没有try的,是不能像其他语言一样,try所有异常。   应用场景:比如某个web,在启动时,数据库都没连接成功,必定要启动失败,就像电脑,没有电源必不能开机一样。   panic 先看一下语法吧   package main    import "fmt"    func say() {      var flag = true      if flag{          //引发错误,直接中断程序的错误          panic("OMG,撤了撤了,必须撤了")  }  }    func main() {      say()      fmt.Println("继续呀...")//不会执行,程序挂了  }  执行效果       可以看淡,继续呀就没打印,程序直接挂了,但是上述好像并没有解决这个问题。   recover 尝试捕捉   代码   package main    import "fmt"    func say() {    //匿名函数,defer执行的是一个匿名函数    defer func() {      var err = recover()      //如果有panic错误,err!=nil,在此处步骤,尝试恢复      if err != nil {        fmt.Println("尝试恢复...")      }    }()    var flag = true    if flag {      panic("OMG,撤了撤了,必须撤了")    }  }    func main() {    say()    fmt.Println("继续呀...")  }  执行结果       可以看到,如果recover捕捉了,并且没有panic,程序就会继续正常执行。   注意 defer必须在panic语句之前。   recover必须配合defer使用。   总结 上述我们学习了Go基础之函数进阶。如果在操作过程中有任何问题,记得下面讨论区留言,我们看到会第一时间解决问题。

(编辑:51站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读