Go의 함수 메모리 할당은 힙 할당과 약간 비슷하지만 본질적으로 동일하지는 않습니다.
힙 메모리처럼 스택도 힙의 주소를 저장하는 것으로 이해할 수 있습니다.
Code
package main import "fmt" func say() string { return "ok" } func main() { fmt.Printf("say栈上的内容:%p\n",say) }
범위의 문제 , 이전에 다소 언급했을 수도 있으므로 다시 검토해 보겠습니다.
전역 변수는 모든 함수 외부에서 정의된 변수입니다. 변수는 프로그램이 끝날 때까지 항상 존재합니다.
当然,任何函数都可以访问全局变量。
注:全局变量尽量全部用大写。
package main import "fmt" var NAME = "张三" func say() string { fmt.Println(NAME) return "ok" } func main() { say() fmt.Println(NAME) }
结果:
上述可能会有个问题,全局变量,全局变量,大家共用一个,要是谁傻不拉几修改了不就完蛋了,整个程序都凉了。
就像这样。
package main import "fmt" var NAME = "张三" func say() string { fmt.Println(NAME) NAME = "李四" return "ok" } func main() { say() fmt.Println(NAME) }
结果:
这不就完犊子了吗???所以,一定要有解决办法。
解决办法:使用常量定义全局变量。
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 }
在Go中,defer
语句,可以理解为在return
之前执行的一个语句。
如果函数没有return
,会有一个默认的return
,只是看不见而已。
代码
package main import "fmt" func say() { //defer尽量往前放 defer fmt.Println("我是666") fmt.Println("你们都是最棒的") } func main() { say() }
执行结果
代码
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会用在释放数据库连接,关闭文件等需要在函数结束时处理的操作。
这里暂时先不举例子。
这俩,可以理解为Python中的try
和raise
,因为在Go中,是没有try
的,是不能像其他语言一样,try
所有异常。
应用场景:比如某个web,在启动时,数据库都没连接成功,必定要启动失败,就像电脑,没有电源必不能开机一样。
先看一下语法吧
package main import "fmt" func say() { var flag = true if flag{ //引发错误,直接中断程序的错误 panic("OMG,撤了撤了,必须撤了") } } func main() { say() fmt.Println("继续呀...")//不会执行,程序挂了 }
执行效果
可以看淡,继续呀
就没打印,程序直接挂了,但是上述好像并没有解决这个问题。
尝试捕捉
代码
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语言基础之函数(中篇)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!