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

解決golang 反射interface{}做零值判斷的一個(gè)重大坑

 更新時(shí)間:2021年04月25日 08:40:16   作者:fwhezfwhez  
這篇文章主要介紹了解決golang 反射interface{}做零值判斷的一個(gè)重大坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

在對(duì)float零值判斷時(shí)往往只需要和0做==即可,所以曾經(jīng)int和float都用==0來(lái)做對(duì)比,

比如下方:

    in := 0.
    var tmp interface{} = float32(in)
    fmt.Println("float 0==0:", in == 0)
    fmt.Println("float -> interface{} -> float", tmp.(float32) == 0)
    switch v := tmp.(type) {
    case float32:
        fmt.Println("float -> interface -.type-> float", v == 0)
    }

結(jié)果:

float 0==0: true

float -> interface{} -> float true

float -> interface -.type-> float true

但是,golang里interface{}對(duì)數(shù)據(jù)的裝箱 相比于 函數(shù)里 [入?yún)?interface{}] 的裝箱是迥然不同的 ,比如:

func f(arg interface{}){
    switch v:=arg.(type) {
    case float32,float64:
        fmt.Println(v==0)
    }
}
func main(){
    f(0.)
}

結(jié)果:

false

我擦咧,竟然是false,暫時(shí)的解決方案就是必須寫成v==0.

//相對(duì)正確的寫法
func f(arg interface{}){
    switch v:=arg.(type) {
    case float32,float64:
        fmt.Println(v==0.)
    case int,int32,in64:
        fmt.Pringtln(v==0)
    }
}

//錯(cuò)誤的寫法
func f(arg interface{}){
    switch v:=arg.(type) {
    case float32,float64,int,int64,int32:
        fmt.Println(v==0)
    }
}

但是,這樣寫還是會(huì)有bug,比如傳一個(gè)float的默認(rèn)值,這個(gè)場(chǎng)景經(jīng)過(guò)仔細(xì)推敲,重現(xiàn)在這里:

func f(arg interface{}){
    switch v:=arg.(type) {
    case float32,float64:
        fmt.Println(v==0.)
    case int,int32,in64:
        fmt.Pringtln(v==0)
    }
}
func main(){
    var i float32
    f(i)
}

結(jié)果:

false

我擦咧,咋回事,還是false

最后經(jīng)過(guò)仔細(xì)查找原因,原來(lái)float的相等判定的解決方案是固定的,因?yàn)橛?jì)算機(jī)內(nèi)部float不存在全等,所以任何兩個(gè)float判定相等方法一定是|a-b|<0.0000001,最終:

func f(arg interface{}){
    switch v:=arg.(type) {
    case float32:
        r:=float64(v)
        fmt.Println(math.Abs(r-0)<0.0000001)
    case float64:
        fmt.Println(math.Abs(v-0)<0.0000001)
    }
}

這里還有最后一個(gè)坑會(huì)踩,那就是switch v:=arg.(type)里的v,在case路由中,如果不能精準(zhǔn)到單路線,v還是一個(gè)interface{}

//編譯器不通過(guò)的寫法,理由是,不支持interface{}類型的v,進(jìn)行float64(v)操作
func f(arg interface{}){
    switch v:=arg.(type) {
    case float32,float64:
        r:=float64(v)
        fmt.Println(math.Abs(r-0)<0.0000001)
}

我擦類~

補(bǔ)充:golang interface{}類型轉(zhuǎn)換 bson.M 遇到莫名其妙的問(wèn)題

背景

從mongo數(shù)據(jù)庫(kù)中取出數(shù)據(jù)以interface{}格式返回,解析返回的數(shù)據(jù)。

1.從mongo中取數(shù)據(jù)

newSession := m.Session.Copy()
defer newSession.Close()
c := newSession.DB(database).C(collName)
if err := c.Find(bson.M{"time": occurtime}).One(&data); err != nil {
		Error(err)
}

2.mongo返回?cái)?shù)據(jù)后 對(duì)interface數(shù)據(jù)進(jìn)行解析

問(wèn)題

問(wèn)題就是出現(xiàn)在解析的時(shí)候報(bào)了錯(cuò)

特地debug了一下queryresult的類型 發(fā)現(xiàn)的確是bson.M 然后他就是報(bào)錯(cuò)

嘗試了各種方法,打了無(wú)數(shù)debug,并沒(méi)發(fā)現(xiàn)問(wèn)題。

解決

最后還是在同事幫助下。。去掉了這里的斷言看看問(wèn)題

看到了panic后的問(wèn)題顯示

第一眼看的一頭霧水。。 bson.M not bson.M

最后想到,這是在兩個(gè)文件下的代碼 然而

一個(gè)引用了服務(wù)本地的mgo包 另一個(gè)則使用了gopath內(nèi)的包所以判斷成了兩個(gè)不一樣的類型 真的是尷尬0.0

教訓(xùn)總結(jié)

同一個(gè)服務(wù)用到的相同包一定要調(diào)同一個(gè)地方的?。?!

同一個(gè)服務(wù)用到的相同包一定要調(diào)同一個(gè)地方的?。?!

同一個(gè)服務(wù)用到的相同包一定要調(diào)同一個(gè)地方的!??!

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • Go語(yǔ)言集成mysql驅(qū)動(dòng)、調(diào)用數(shù)據(jù)庫(kù)、查詢數(shù)據(jù)操作示例

    Go語(yǔ)言集成mysql驅(qū)動(dòng)、調(diào)用數(shù)據(jù)庫(kù)、查詢數(shù)據(jù)操作示例

    這篇文章主要介紹了Go語(yǔ)言集成mysql驅(qū)動(dòng)、調(diào)用數(shù)據(jù)庫(kù)、查詢數(shù)據(jù)操作,結(jié)合實(shí)例形式分析了Go語(yǔ)言安裝mysql驅(qū)動(dòng)包、連接mysql數(shù)據(jù)庫(kù)及查詢等相關(guān)操作技巧,需要的朋友可以參考下
    2019-06-06
  • Golang讀寫二進(jìn)制文件方法總結(jié)

    Golang讀寫二進(jìn)制文件方法總結(jié)

    使用?Golang?的?encoding/gob?包讀寫二進(jìn)制文件非常方便,而且代碼量也非常少,本文就來(lái)通過(guò)兩個(gè)示例帶大家了解一下encoding/gob的具體用法吧
    2023-05-05
  • GoLang切片并發(fā)安全解決方案詳解

    GoLang切片并發(fā)安全解決方案詳解

    這篇文章主要介紹了GoLang切片并發(fā)安全問(wèn)題的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-10-10
  • 簡(jiǎn)單講解Go程序中使用MySQL的方法

    簡(jiǎn)單講解Go程序中使用MySQL的方法

    這篇文章主要介紹了Go程序中使用MySQL的方法,需要使用第三方包來(lái)進(jìn)行連接,需要的朋友可以參考下
    2015-10-10
  • 一文吃透Go的內(nèi)置RPC原理

    一文吃透Go的內(nèi)置RPC原理

    這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言中內(nèi)置RPC的原理。說(shuō)起?RPC?大家想到的一般是框架,Go?作為編程語(yǔ)言竟然還內(nèi)置了?RPC,著實(shí)讓我有些吃鯨,本文就來(lái)一起聊聊吧
    2023-03-03
  • Go調(diào)用opencv實(shí)現(xiàn)圖片矯正的代碼示例

    Go調(diào)用opencv實(shí)現(xiàn)圖片矯正的代碼示例

    這篇文章主要為大家詳細(xì)介紹了Go調(diào)用opencv實(shí)現(xiàn)圖片矯正的代碼示例,文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-09-09
  • Golang并發(fā)操作中常見的讀寫鎖詳析

    Golang并發(fā)操作中常見的讀寫鎖詳析

    Golang中的鎖機(jī)制主要包含互斥鎖和讀寫鎖互斥鎖互斥鎖是傳統(tǒng)并發(fā)程序?qū)蚕碣Y源進(jìn)行控制訪問(wèn)的主要手段,這篇文章主要給大家介紹了關(guān)于Golang并發(fā)操作中常見的讀寫鎖的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • Golang學(xué)習(xí)之內(nèi)存逃逸分析

    Golang學(xué)習(xí)之內(nèi)存逃逸分析

    內(nèi)存逃逸分析是go的編譯器在編譯期間,根據(jù)變量的類型和作用域,確定變量是堆上還是棧上。本文將帶大家分析一下Golang中的內(nèi)存逃逸,需要的可以了解一下
    2023-01-01
  • Go語(yǔ)言中的goroutine和channel如何協(xié)同工作

    Go語(yǔ)言中的goroutine和channel如何協(xié)同工作

    在Go語(yǔ)言中,goroutine和channel是并發(fā)編程的兩個(gè)核心概念,它們協(xié)同工作以實(shí)現(xiàn)高效、安全的并發(fā)執(zhí)行,本文將詳細(xì)探討goroutine和channel如何協(xié)同工作,以及它們?cè)诓l(fā)編程中的作用和優(yōu)勢(shì),需要的朋友可以參考下
    2024-04-04
  • Go語(yǔ)言中Timer計(jì)時(shí)器的使用技巧詳解

    Go語(yǔ)言中Timer計(jì)時(shí)器的使用技巧詳解

    Go語(yǔ)言中的time包里有個(gè)Timer計(jì)時(shí)器的功能,這篇文章主要就是來(lái)和大家介紹一下Timer計(jì)時(shí)器的使用技巧,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-07-07

最新評(píng)論

莱芜市| 铜鼓县| 三台县| 白城市| 昌黎县| 秭归县| 阿克陶县| 安义县| 加查县| 蛟河市| 邵阳市| 西藏| 克什克腾旗| 常山县| 博罗县| 临澧县| 理塘县| 京山县| 桂平市| 小金县| 仙桃市| 遂川县| 鄱阳县| 旺苍县| 镇江市| 广德县| 新民市| 咸阳市| 贵州省| 宁河县| 托克托县| 神木县| 哈尔滨市| 鱼台县| 南召县| 芮城县| 永城市| 黔西县| 龙里县| 屯门区| 克东县|