Heim  >  Artikel  >  Backend-Entwicklung  >  Ein Artikel, der Ihnen hilft, die Grundfunktionen der Go-Sprache zu verstehen (Teil 2)

Ein Artikel, der Ihnen hilft, die Grundfunktionen der Go-Sprache zu verstehen (Teil 2)

Go语言进阶学习
Go语言进阶学习nach vorne
2023-07-25 14:17:311318Durchsuche

Go-Funktionsspeicherzuordnungsdiagramm

Die Funktionsspeicherzuordnung von Go ähnelt ein wenig der Heap-Zuordnung, ist aber im Wesentlichen nicht dasselbe.

Ein Artikel, der Ihnen hilft, die Grundfunktionen der Go-Sprache zu verstehen (Teil 2)

Es ist verständlich, dass der Stapel wie der Heapspeicher die Adresse des Heaps speichert.

Verifizierung

Code

package main


import "fmt"




func say() string {
    return "ok"
}


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

Ergebnis

Ein Artikel, der Ihnen hilft, die Grundfunktionen der Go-Sprache zu verstehen (Teil 2)

Essenz

Ein Artikel, der Ihnen hilft, die Grundfunktionen der Go-Sprache zu verstehen (Teil 2)

Funktionsumfang

Das Problem des Umfangs, I Ich habe es vielleicht schon mehr oder weniger erwähnt, also schauen wir es uns noch einmal an.

Globale Variablen

Globale Variablen sind Variablen, die außerhalb aller Funktionen definiert sind. Die Variablen bleiben immer vorhanden, bis das Programm endet.

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

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

小试牛刀

package main


import "fmt"




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


func main() {
    say()
    fmt.Println(NAME)
}

结果:

Ein Artikel, der Ihnen hilft, die Grundfunktionen der Go-Sprache zu verstehen (Teil 2)

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

var引发的问题

就像这样。

package main


import "fmt"


var NAME = "张三"


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


func main() {
    say()
    fmt.Println(NAME)
}

结果:

Ein Artikel, der Ihnen hilft, die Grundfunktionen der Go-Sprache zu verstehen (Teil 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)


}

总结

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

执行结果

Ein Artikel, der Ihnen hilft, die Grundfunktionen der Go-Sprache zu verstehen (Teil 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()
}

执行结果

Ein Artikel, der Ihnen hilft, die Grundfunktionen der Go-Sprache zu verstehen (Teil 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("继续呀...")//不会执行,程序挂了
}

执行效果

Ein Artikel, der Ihnen hilft, die Grundfunktionen der Go-Sprache zu verstehen (Teil 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("继续呀...")
}

执行结果

Ein Artikel, der Ihnen hilft, die Grundfunktionen der Go-Sprache zu verstehen (Teil 2)

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

注意

defer必须在panic语句之前。

recover必须配合defer使用。

Das obige ist der detaillierte Inhalt vonEin Artikel, der Ihnen hilft, die Grundfunktionen der Go-Sprache zu verstehen (Teil 2). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:Go语言进阶学习. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen