最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

前言

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

問(wèn)題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 兩兩相等

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

正確寫法

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

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

問(wèn)題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
}

而我們?cè)谕獠拷邮盏藉e(cuò)誤之后常常會(huì)使用 errors.Is 來(lái)判斷錯(cuò)誤類型:

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

但是會(huì)發(fā)現(xiàn)上面這個(gè)判斷無(wú)論如何都是 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)無(wú)法成功比較。

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

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

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

參考

[1]深入理解 Go Comparable Type

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

相關(guān)文章

  • 從基礎(chǔ)到高階解析Go語(yǔ)言中數(shù)組的應(yīng)用

    從基礎(chǔ)到高階解析Go語(yǔ)言中數(shù)組的應(yīng)用

    在本文中,我們將從基礎(chǔ)概念、常規(guī)操作,到高級(jí)技巧和特殊操作,帶大家深入了解Go語(yǔ)言中數(shù)組的各個(gè)方面,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-10-10
  • Golang因Channel未關(guān)閉導(dǎo)致內(nèi)存泄漏的解決方案詳解

    Golang因Channel未關(guān)閉導(dǎo)致內(nèi)存泄漏的解決方案詳解

    這篇文章主要為大家詳細(xì)介紹了當(dāng)Golang因Channel未關(guān)閉導(dǎo)致內(nèi)存泄漏時(shí)蓋如何解決,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-07-07
  • go語(yǔ)言make初始化的實(shí)現(xiàn)

    go語(yǔ)言make初始化的實(shí)現(xiàn)

    Go語(yǔ)言中的make函數(shù)用于初始化切片、映射和通道,本文就來(lái)介紹一下go語(yǔ)言make初始化的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-12-12
  • Go語(yǔ)言Zap庫(kù)Logger的定制化和封裝使用詳解

    Go語(yǔ)言Zap庫(kù)Logger的定制化和封裝使用詳解

    這篇文章主要介紹了Go語(yǔ)言Zap庫(kù)Logger的定制化和封裝使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • idea搭建go環(huán)境實(shí)現(xiàn)go語(yǔ)言開發(fā)

    idea搭建go環(huán)境實(shí)現(xiàn)go語(yǔ)言開發(fā)

    這篇文章主要給大家介紹了關(guān)于idea搭建go環(huán)境實(shí)現(xiàn)go語(yǔ)言開發(fā)的相關(guān)資料,文中通過(guò)圖文介紹以及代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用go具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-01-01
  • Golang 中的直接依賴和間接依賴管理詳解

    Golang 中的直接依賴和間接依賴管理詳解

    在 Golang 中,依賴管理是非常重要的,直接依賴是指項(xiàng)目代碼中明確引用的其他包的依賴,而間接依賴是指直接依賴所引用的其他包的依賴,這篇文章主要介紹了Golang 中的直接依賴和間接依賴管理,需要的朋友可以參考下
    2023-11-11
  • 一文告訴你大神是如何學(xué)習(xí)Go語(yǔ)言之make和new

    一文告訴你大神是如何學(xué)習(xí)Go語(yǔ)言之make和new

    當(dāng)我們想要在 Go 語(yǔ)言中初始化一個(gè)結(jié)構(gòu)時(shí),其實(shí)會(huì)使用到兩個(gè)完全不同的關(guān)鍵字,也就是 make 和 new,同時(shí)出現(xiàn)兩個(gè)用于『初始化』的關(guān)鍵字對(duì)于初學(xué)者來(lái)說(shuō)可能會(huì)感到非常困惑,不過(guò)它們兩者有著卻完全不同的作用,本文就和大家詳細(xì)講講
    2023-02-02
  • go 微服務(wù)框架kratos使用中間件的方法

    go 微服務(wù)框架kratos使用中間件的方法

    在go語(yǔ)言中,中間件是一種用于處理http請(qǐng)求的開發(fā)模式,允許開發(fā)人員在請(qǐng)求到達(dá)處理程序之前或之后執(zhí)行特定的操作,如日志記錄、身份驗(yàn)證、錯(cuò)誤處理等,這篇文章主要介紹了go 微服務(wù)框架kratos使用中間件的方法,需要的朋友可以參考下
    2024-05-05
  • golang 微服務(wù)之gRPC與Protobuf的使用

    golang 微服務(wù)之gRPC與Protobuf的使用

    這篇文章主要介紹了golang 微服務(wù)之gRPC與Protobuf的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • Golang Map簡(jiǎn)介以及底層原理

    Golang Map簡(jiǎn)介以及底層原理

    這篇文章主要介紹了Golang Map簡(jiǎn)介以及底層原理的相關(guān)資料,Go語(yǔ)言提供的map是一種鍵值對(duì)存儲(chǔ)結(jié)構(gòu),支持基本操作如len、delete等,map是非線程安全的,可用sync.Mutex確保并發(fā)安全,為高效查找和插入,需要的朋友可以參考下
    2024-10-10

最新評(píng)論

拉萨市| 宝鸡市| 肥乡县| 龙泉市| 高碑店市| 朔州市| 天峻县| 福海县| 盈江县| 兴和县| 宁国市| 湘阴县| 东阳市| 潢川县| 谢通门县| 林周县| 丹寨县| 虎林市| 嘉祥县| 镇原县| 黄浦区| 土默特右旗| 封丘县| 隆昌县| 信丰县| 静乐县| 易门县| 益阳市| 黄梅县| 滕州市| 敦煌市| 凤城市| 阳春市| 瓦房店市| 和政县| 和田县| 彭山县| 手机| 东明县| 大厂| 金乡县|