当前位置: 首页 > 科技观察

一文带你了解Go语言的基本功能(下)

时间:2023-03-21 14:25:47 科技观察

前言大家好,我是星期五,在上一篇文章中学习了一些基础知识:Go语言(上),本期继续学习Go基础的高级功能。Go函数内存分配图Go的函数内存分配有点像堆分配,有点类似,但本质上不是。可以理解为和堆内存一样,堆的地址存放在栈中。验证码packagemainimport"fmt"funcsay()string{return"ok"}funcmain(){fmt.Printf("saycontentonthestack:%p\n",say)}resultthescopeofessentialfunctionscope这个问题,之前可能或多或少提到过,我们再回顾一下。全局变量全局变量是定义在所有函数之外的变量,该变量会一直存在到程序结束。当然,任何函数都可以访问全局变量。注意:所有全局变量尽量大写。小测试packagemainimport"fmt"varNAME="张三"funcsay()string{fmt.Println(NAME)return"ok"}funcmain(){say()fmt.Println(NAME)}结果:上面可能有问题,globalvariables,globalvariables,大家共享一个,谁傻了不修改几次就完了,整个程序就凉了。var提出的问题是这样的。packagemainimport"fmt"varNAME="张三"funcsay()string{fmt.Println(NAME)NAME="李四"return"ok"}funcmain(){say()fmt.Println(NAME)}结果:这是不是结束了吗???所以,必须有一个解决方案。使用const解决问题解决方法:使用常量定义全局变量。packagemainimport"fmt"constNAME="张三"funcsay()string{fmt.Println(NAME)//NAME="李四"//会报错:cannotassigntoNAMEreturn"ok"}funcmain(){say()fmt.Println(NAME)}总结定义全局变量时,需要用const修饰,变量名全部大写。局部变量局部变量,局部变量是定义在函数内部的变量,只能在自己的函数内部使用。说的专业些,{}中定义的东西只能用在{}中,for也是一样。代码packagemainimport("fmt")funcsay()string{varname="张三"fmt.Println(name)return"ok"}funcmain(){say()//fmt.Println(name)//会报错:undefined:name//for等同于fori:=0;i<=1;i++{varc="66"fmt.Println(c)//66}//fmt.Println(c)//会报报错:undefined:c}defer在Go中,defer语句可以理解为在return之前执行的语句。如果函数没有返回值,默认会有返回值,只是不可见。一个defer代码packagemainimport"fmt"funcsay(){//尽可能延迟deferfmt.Println("我是666")fmt.Println("你们都是最棒的")}funcmain(){say()}执行resultmultipledefercodepackagemainimport"fmt"funcsay(){//defer尝试提出")}funcmain(){say()}执行结果显示defer的执行结果是相反的。结论:先执行的defer会最后执行,最后执行的defer会先执行,有点像栈,先进后出。需要在函数末尾处理,这里暂且不举例。panic和recover可以理解为Python中的try和raise,因为在Go中,没有try,不能像其他的一样尝试所有的异常languages.应用场景:比如某web启动时,数据库没有连接成功,必须无法启动,就像电脑没有电源就无法开机一样。我们先来看看语法。packagemainimport"fmt"funcsay(){varflag=trueifflag{//报错直接中断程序报错panic("天啊,已经撤回了,必须撤回")}}funcmain(){say()fmt.println("Continue...")//不会执行,程序挂了}执行效果可以说是无足轻重,继续的话就没有打印,程序直接挂了,但是上面确实似乎不能解决这个问题。recover尝试捕获代码packagemainimport"fmt"funcsay(){//匿名函数,defer执行一个匿名函数deferfunc(){varerr=recover()//如果出现panic错误,err!=nil,这里是step,Trytorestoreiferr!=nil{fmt.Println("Trytorestore...")}}()varflag=trueifflag{panic("OMG,没了,必须做")}}funcmain(){say()fmt.Println("Continue...")}执行结果可以看到,如果recover被捕获,没有panic,程序会继续正常执行。注意defer必须在panic语句之前。recover必须与defer一起使用。综上所述,我们学习了Go基础的进阶功能。如果您在操作过程中有什么问题,记得在下方讨论区留言,我们看到会第一时间解决。本文转载自微信公众号《Go语言进阶学习》,可通过以下二维码关注。转载本文请联系Go语言进阶学习公众号。