Maison > développement back-end > Golang > le corps du texte

Un article pour vous aider à comprendre les fonctions de base du langage Go (Partie 2)

Libérer: 2023-07-25 14:17:31
avant
1331 Les gens l'ont consulté

Schéma d'allocation de mémoire de fonction Go

L'allocation de mémoire de fonction de Go est un peu comme l'allocation de tas, mais ce n'est pas essentiellement la même chose.

Un article pour vous aider à comprendre les fonctions de base du langage Go (Partie 2)

On peut comprendre que comme la mémoire du tas, la pile stocke l'adresse du tas.

Vérification

Code

package main


import "fmt"




func say() string {
    return "ok"
}


func main() {
    fmt.Printf("say栈上的内容:%p\n",say)
}
Copier après la connexion

Résultat

Un article pour vous aider à comprendre les fonctions de base du langage Go (Partie 2)

Essence

Un article pour vous aider à comprendre les fonctions de base du langage Go (Partie 2)

Le périmètre de la fonction

Le problème du périmètre , je l'ai peut-être mentionné plus ou moins auparavant, alors revoyons-le à nouveau.

Variables globales

Les variables globales sont des variables définies en dehors de toutes les fonctions. Les variables existeront toujours jusqu'à la fin du programme.

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

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

小试牛刀

package main


import "fmt"




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


func main() {
    say()
    fmt.Println(NAME)
}
Copier après la connexion

结果:

Un article pour vous aider à comprendre les fonctions de base du langage Go (Partie 2)

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

var引发的问题

就像这样。

package main


import "fmt"


var NAME = "张三"


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


func main() {
    say()
    fmt.Println(NAME)
}
Copier après la connexion

结果:

Un article pour vous aider à comprendre les fonctions de base du langage Go (Partie 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)


}
Copier après la connexion

总结

在定义全局变量时,需要用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
}
Copier après la connexion

defer

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

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

一个defer

代码

package main


import "fmt"


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


func main() {
    say()
}
Copier après la connexion

执行结果

Un article pour vous aider à comprendre les fonctions de base du langage Go (Partie 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()
}
Copier après la connexion

执行结果

Un article pour vous aider à comprendre les fonctions de base du langage Go (Partie 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("继续呀...")//不会执行,程序挂了
}
Copier après la connexion

执行效果

Un article pour vous aider à comprendre les fonctions de base du langage Go (Partie 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("继续呀...")
}
Copier après la connexion

执行结果

Un article pour vous aider à comprendre les fonctions de base du langage Go (Partie 2)

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

注意

defer必须在panic语句之前。

recover必须配合defer使用。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:Go语言进阶学习
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal