欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go 函數(shù)返回nil遇到問題避坑分析

 更新時(shí)間:2023年01月06日 11:55:26   作者:nil  
這篇文章主要為大家介紹了Go 函數(shù)返回nil遇到的避坑問題分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

go語言寫函數(shù)時(shí)經(jīng)常返回nil,然后在函數(shù)外面判斷返回值是否為空。這里有個(gè)bug,記錄一下

問題1

(*Type)(nil) ≠ nil

func returnsError() error {
	var p *MyError = nil
	if bad() {
		p = ErrBad
	}
	return p // Will always return a non-nil error.
}

上面函數(shù)returnsError返回的 p 永遠(yuǎn)不會(huì)與 nil 相等。

這是為什么呢,因?yàn)?error 是一個(gè) interface,interface 之間比較需要保證兩者的 Type 和 Value 兩兩相等

語言內(nèi)的 nil 可以理解為一個(gè) Type 和 Value 均為空的 interface 代碼里面返回的 p 雖然 Value 為空,但是 Type 是 *MyError 所以 p!=nil 。

正確寫法

func returnsError() error {
	if bad() {
		return ErrBad
	}
	return nil
}

這個(gè)問題不僅僅是拋出錯(cuò)誤的時(shí)候會(huì)出現(xiàn),任何返回 interface 的場景都需要注意。

問題2

type CustomError struct {
	Metadata map[string]string
	Message string
}
func (c CustomError) Error() string {
		return c.Message
}
var (
	ErrorA = CustomError{Message:"A", Matadata: map[string]string{"Reason":""}}
	ErrorB = CustomError{Message:"B"}
)
func DoSomething() error {
	return ErrorA
}

而我們在外部接收到錯(cuò)誤之后常常會(huì)使用 errors.Is 來判斷錯(cuò)誤類型:

err:=DoSomething()
if errors.Is(err, ErrorA) {
	// handle err
}

但是會(huì)發(fā)現(xiàn)上面這個(gè)判斷無論如何都是 false。研究一下 errors.Is 的源碼:

func Is(err, target error) bool {
	if target == nil {
		return err == target
	}
	isComparable := reflect.TypeOf(target).Comparable()
	for {
		if isComparable && err == target {
			return true
		}
		if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
			return true
		}
		if err = errors.Unwrap(err); err == nil {
			return false
		}
	}
}

可以看到這是一個(gè)在 error tree 上遞歸的流程,真值的終結(jié)條件是 err==target ,但是前提是 target 本身得是 comparable 的

所以如果我們把一個(gè) map 放入了 error struct,就導(dǎo)致這個(gè) error 變?yōu)?incomparable,永遠(yuǎn)無法成功比較。

解決方案也很簡單,就是將 Error 定義指針類型:

var (
	ErrorA = &CustomError{Message:"A", Matadata: map[string]string{"Reason":""}}
	ErrorB = &CustomError{Message:"B"}
)

指針類型比較只需要是否檢查是否指向同一個(gè)對象,這樣就能順利比較了。

參考

[1]深入理解 Go Comparable Type

以上就是Go 函數(shù)返回nil遇到問題避坑分析的詳細(xì)內(nèi)容,更多關(guān)于Go 函數(shù)返回nil避坑的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 基于Go和Gin的環(huán)境配置方法

    基于Go和Gin的環(huán)境配置方法

    今天小編就為大家分享一篇基于Go和Gin的環(huán)境配置方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • 幾個(gè)小技巧幫你實(shí)現(xiàn)Golang永久阻塞

    幾個(gè)小技巧幫你實(shí)現(xiàn)Golang永久阻塞

    Go 的運(yùn)行時(shí)的當(dāng)前設(shè)計(jì),假定程序員自己負(fù)責(zé)檢測何時(shí)終止一個(gè) goroutine 以及何時(shí)終止該程序。有時(shí)候我們需要的是使程序阻塞在這一行,本文就來詳細(xì)的介紹一下,感興趣的可以了解一下
    2021-12-12
  • Golang 按行讀取文件的三種方法小結(jié)

    Golang 按行讀取文件的三種方法小結(jié)

    本文主要介紹了Golang 按行讀取文件的三種方法小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 如何避免Go語言常見錯(cuò)誤之意外的變量隱藏

    如何避免Go語言常見錯(cuò)誤之意外的變量隱藏

    在Go語言中,變量隱藏(Variable Shadowing)是一個(gè)常見的錯(cuò)誤來源,變量隱藏發(fā)生在一個(gè)內(nèi)部作用域中聲明的變量與外部作用域的變量同名時(shí),這可能導(dǎo)致開發(fā)者無意中使用了錯(cuò)誤的變量,造成難以追蹤的bug,本文講解一些關(guān)于變量隱藏的常見錯(cuò)誤和如何避免它們的方法
    2024-01-01
  • go語言調(diào)用c語言的so動(dòng)態(tài)庫的實(shí)現(xiàn)

    go語言調(diào)用c語言的so動(dòng)態(tài)庫的實(shí)現(xiàn)

    在Go語言開發(fā)過程中,有時(shí)需要調(diào)用C或C++編寫的so動(dòng)態(tài)庫,本文介紹了如何在Go語言中調(diào)用so庫的步驟和注意事項(xiàng),包括環(huán)境準(zhǔn)備、編譯生成.so文件、Go文件編寫、以及可能遇到的問題和解決方法,感興趣的可以了解一下
    2024-10-10
  • go實(shí)現(xiàn)反轉(zhuǎn)鏈表

    go實(shí)現(xiàn)反轉(zhuǎn)鏈表

    這篇文章主要介紹了go實(shí)現(xiàn)反轉(zhuǎn)鏈表的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Go 微服務(wù)開發(fā)框架DMicro設(shè)計(jì)思路詳解

    Go 微服務(wù)開發(fā)框架DMicro設(shè)計(jì)思路詳解

    這篇文章主要為大家介紹了Go 微服務(wù)開發(fā)框架DMicro設(shè)計(jì)思路詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • 使用Go語言編寫HTTP中間件的示例詳解

    使用Go語言編寫HTTP中間件的示例詳解

    在Go語言中,HTTP中間件是一種處理HTTP請求和響應(yīng)的函數(shù),它可以攔截到請求并對其進(jìn)行處理,然后再將請求傳遞給下一個(gè)中間件或目標(biāo)處理程序,本文給大家介紹了使用Go語言編寫HTTP中間件的示例,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2024-01-01
  • go的strings用法小結(jié)

    go的strings用法小結(jié)

    strings 是 Go 語言標(biāo)準(zhǔn)庫中提供的一個(gè)包,用于處理字符串相關(guān)的操作,本文主要介紹了go的strings用法小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-08-08
  • Go語言的GOPATH與工作目錄詳解

    Go語言的GOPATH與工作目錄詳解

    這篇文章主要介紹了Go語言的GOPATH與工作目錄詳解,本文詳細(xì)講解了GOPATH設(shè)置、應(yīng)用目錄結(jié)構(gòu)、編譯應(yīng)用等內(nèi)容,需要的朋友可以參考下
    2014-10-10

最新評(píng)論