自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go 語言怎么解決編譯器錯(cuò)誤“err is shadowed during return”?

開發(fā) 前端
本文我們介紹為什么會出現(xiàn)該錯(cuò)誤,以及我們應(yīng)該怎么解決?

1介紹

在 Go 語言開發(fā)中,我們可能會遇到“錯(cuò)誤在返回時(shí)被隱藏”的錯(cuò)誤,該錯(cuò)誤在 Go 編碼時(shí)很難發(fā)現(xiàn),在 GoLand 中也只是會變量名高亮提示,只有在編譯 Go 項(xiàng)目時(shí),Go 編譯器會返回 err is shadowed during return。

本文我們介紹為什么會出現(xiàn)該錯(cuò)誤,以及我們應(yīng)該怎么解決?

2.為什么出現(xiàn)該錯(cuò)誤?

示例代碼:

package main

import (
"errors"
"log"
)

func main() {
err := foo()
if err != nil {
log.Printf("err=%v\n", err)
return
}
}

func foo() (err error) {
if err := bar(); err != nil {
return // Compiler reports: err is shadowed during return
}
return nil
}

func bar() error {
err := errors.New("this is bar's err")
return err
}

輸出結(jié)果:

./main.go:18:3: err is shadowed during return

閱讀上面這段代碼,我們在編譯代碼時(shí),編譯器返回錯(cuò)誤“err is shadowed during return”。

因?yàn)楹瘮?shù) func foo() (err error)? 的返回值是具名參數(shù),其作用域是函數(shù) foo()? 的函數(shù)體,在函數(shù)體中,if? 分支使用短變量聲明的方式重新聲明變量 err?,它的作用域是 if 分支。

在 if? 分支聲明的變量 err?,它的內(nèi)存地址與外層變量 err? 不是同一個(gè)內(nèi)存地址,而在 if? 分支中使用 return? 返回的是外層變量 err?,所以 if? 分支中的變量 err? 被外層變量 err 所遮蔽,導(dǎo)致在編譯 Go 項(xiàng)目時(shí),Go 編譯器返回錯(cuò)誤“err is shadowed during return”。

3.怎么解決?

閱讀完 Part02,讀者朋友們已經(jīng)了解了錯(cuò)誤的原因。實(shí)際上,出現(xiàn)該錯(cuò)誤,歸根結(jié)底是我們沒有真正掌握 Go 的基礎(chǔ)知識。

為什么這么說呢?因?yàn)樵谖覀児娞柕臍v史文章中,關(guān)于 Go 變量聲明、作用域、函數(shù)等基礎(chǔ)知識都有介紹。

如果讀者朋友們徹底掌握這些基礎(chǔ)知識,大概率是不會遇到該錯(cuò)誤“err is shadowed during return”。

解決該錯(cuò)誤也比較簡單,錯(cuò)誤的原因是變量被遮蔽,我們通過使用不同的變量名,可以輕松規(guī)避這個(gè)錯(cuò)誤。

示例代碼:

...
func foo() (err error) {
if err1 := bar(); err1 != nil {
return
}
return nil
}
...

但是,使用不同的變量名真的解決問題了嗎?

我們運(yùn)行使用不同變量名的代碼,確實(shí) Go 編譯器沒有返回錯(cuò)誤,我們可以正常編譯 Go 項(xiàng)目。

細(xì)心的讀者朋友們可能已經(jīng)發(fā)現(xiàn),該解決方案雖然可以規(guī)避 Go 編譯器返回錯(cuò)誤,但是并沒有將錯(cuò)誤傳遞到外層變量 err。

所以,我們還需要將新變量 err1 的值賦值給外層變量 err,代碼如下:

...
func foo() (err error) {
if err1 := bar(); err1 != nil {
err = err1
return
}
return nil
}
...

現(xiàn)在,我們才算徹底解決了問題。改造后的代碼,既不會引起 Go 編譯器返回錯(cuò)誤,也可以將錯(cuò)誤信息傳遞出去。

讀者朋友們?nèi)绻写a“潔癖”,肯定覺得這么寫代碼太不優(yōu)雅了。那么,有沒有優(yōu)雅的解決方案呢?

答案是有更優(yōu)雅的解決方案,我們在講變量作用域的文章中也有講過,在具名返回值的函數(shù)中,如果在函數(shù)體不同作用域中使用同名變量,不能直接返回,而是需要在 return 后面跟上變量名。

func foo() (err error) {
if err := bar(); err != nil {
return err
}
return nil
}

閱讀上面這段代碼,我們在 if? 分支的作用域中,在 return? 后面跟上變量名 err,該方式也可以解決問題,而且比使用不同變量名的方式更優(yōu)雅。

現(xiàn)在,我們學(xué)會了兩種解決方案。但是,還沒有結(jié)束。我們示例代碼中,調(diào)用函數(shù) bar 是單返回值,在實(shí)際項(xiàng)目開發(fā)中,還會遇到調(diào)用函數(shù)是多返回值。

package main

import (
"errors"
"log"
)

func main() {
err := foo()
if err != nil {
log.Printf("err=%v\n", err)
return
}
}

func foo() (err error) {
if code, err := bar(); err != nil {
log.Printf("code=%v err=%v\n", code, err)
return // Compiler reports: err is shadowed during return
}
return nil
}

func bar() (int, error) {
err := errors.New("this is bar's err")
return 200, err
}

輸出結(jié)果:

./main.go:19:3: err is shadowed during return

閱讀上面這段代碼,調(diào)用函數(shù) bar() 是多返回值。

對于調(diào)用函數(shù)是多返回值的情況,除了我們已經(jīng)講的兩種解決方式,還有其它解決方式。

...
func foo() (err error) {
var code int
if code, err = bar(); err != nil {
log.Printf("code=%v err=%v\n", code, err)
return
}
return nil
}
...

閱讀上面這段代碼,我們單獨(dú)聲明新變量 code?,而不是使用短變量的方式聲明新變量 code?,避免變量 err 也被重新聲明。

4.總結(jié)

本文我們介紹 Go 語言編譯錯(cuò)誤 err is shadowed during return 的原因和解決方案。先是介紹出現(xiàn)該錯(cuò)誤的原因,然后介紹了解決該錯(cuò)誤的三種解決方式。

需要注意的是,我們示例代碼 foo 函數(shù)是具名返回值,本文講的解決方案并不適用于匿名返回值的函數(shù)。

參考資料:

https://groups.google.com/g/golang-nuts/c/HmmZXC7KcVw?pli=1

https://go.dev/ref/spec#Short_variable_declarations

責(zé)任編輯:武曉燕 來源: Golang語言開發(fā)棧
相關(guān)推薦

2013-12-30 11:21:31

Go編譯器

2022-06-13 07:03:25

Go 語言怎么優(yōu)化重

2021-09-06 07:59:13

Go編譯器語言

2023-08-22 08:00:00

編譯器開發(fā)RustOCaml

2025-03-13 07:32:26

2021-08-22 17:18:58

Go代碼泛型代碼

2021-05-13 18:53:34

Go編譯器Uber

2010-01-21 09:11:38

C++編譯器

2010-03-23 11:17:16

Python 動態(tài)編譯

2010-01-18 10:34:21

C++編譯器

2009-08-10 17:12:54

C#編譯器

2017-03-20 18:01:55

編譯器匯編

2013-03-29 10:02:37

編譯器語言編譯開發(fā)

2020-12-17 06:25:05

Gopanic 模式

2020-10-26 11:33:45

編程語言編譯器軟件

2012-03-26 14:25:34

C++

2020-11-10 13:42:07

Go編譯器修復(fù)

2010-10-20 13:43:37

C++編譯器

2019-08-06 08:20:07

編譯器工具開發(fā)者

2013-12-10 10:53:47

shellcode
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號