An article to help you understand the basic functions of Go language (Part 2)

Release: 2023-07-25 14:17:31
forward
1330 people have browsed it

Go function memory allocation diagram

Go's function memory allocation is a bit like heap allocation, but it is not essentially the same.

An article to help you understand the basic functions of Go language (Part 2)

It can be understood that like heap memory, the stack stores the address of the heap.

Verification

Code

package main


import "fmt"




func say() string {
    return "ok"
}


func main() {
    fmt.Printf("say栈上的内容:%p\n",say)
}
Copy after login

Result

An article to help you understand the basic functions of Go language (Part 2)

Essence

An article to help you understand the basic functions of Go language (Part 2)

function Scope

#The issue of scope may have been raised more or less before, so let’s review it again.

Global variables

Global variables are variables defined outside all functions. The variables will always exist until the program ends.

当然,任何函数都可以访问全局变量。

注:全局变量尽量全部用大写。

小试牛刀

package main


import "fmt"




var NAME = "张三"
func say() string {
    fmt.Println(NAME)
    return "ok"
}


func main() {
    say()
    fmt.Println(NAME)
}
Copy after login

结果:

An article to help you understand the basic functions of Go language (Part 2)

上述可能会有个问题,全局变量,全局变量,大家共用一个,要是谁傻不拉几修改了不就完蛋了,整个程序都凉了。

var引发的问题

就像这样。

package main


import "fmt"


var NAME = "张三"


func say() string {
    fmt.Println(NAME)
    NAME = "李四"
    return "ok"
}


func main() {
    say()
    fmt.Println(NAME)
}
Copy after login

结果:

An article to help you understand the basic functions of Go language (Part 2)

这不就完犊子了吗???所以,一定要有解决办法。

使用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)


}
Copy after login

总结

在定义全局变量时,需要用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
}
Copy after login

defer

在Go中,defer语句,可以理解为在return之前执行的一个语句。

如果函数没有return,会有一个默认的return,只是看不见而已。

一个defer

代码

package main


import "fmt"


func say() {
    //defer尽量往前放
    defer fmt.Println("我是666")
    fmt.Println("你们都是最棒的")
}


func main() {
    say()
}
Copy after login

执行结果

An article to help you understand the basic functions of Go language (Part 2)

多个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()
}
Copy after login

执行结果

An article to help you understand the basic functions of Go language (Part 2)

可以发现,defer的执行结果是反着的。

结论:先执行的defer,会最后执行,最后执行的defer,会最先执行,有点像栈,先进后出

defer的作用

通常来说,defer会用在释放数据库连接,关闭文件等需要在函数结束时处理的操作。

这里暂时先不举例子。


panic和recover

这俩,可以理解为Python中的tryraise,因为在Go中,是没有try的,是不能像其他语言一样,try所有异常。

应用场景:比如某个web,在启动时,数据库都没连接成功,必定要启动失败,就像电脑,没有电源必不能开机一样。

panic

先看一下语法吧

package main


import "fmt"


func say() {
    var flag = true
    if flag{
        //引发错误,直接中断程序的错误
        panic("OMG,撤了撤了,必须撤了")
}
}


func main() {
    say()
    fmt.Println("继续呀...")//不会执行,程序挂了
}
Copy after login

执行效果

An article to help you understand the basic functions of Go language (Part 2)

可以看淡,继续呀就没打印,程序直接挂了,但是上述好像并没有解决这个问题。

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("继续呀...")
}
Copy after login

执行结果

An article to help you understand the basic functions of Go language (Part 2)

可以看到,如果recover捕捉了,并且没有panic,程序就会继续正常执行。

注意

defer必须在panic语句之前。

recover必须配合defer使用。

The above is the detailed content of An article to help you understand the basic functions of Go language (Part 2). For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:Go语言进阶学习
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template