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

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

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

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

比如下方:

    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{}對數(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.

//相對正確的寫法
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è)場景經(jīng)過仔細(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)過仔細(xì)查找原因,原來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{}

//編譯器不通過的寫法,理由是,不支持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 遇到莫名其妙的問題

背景

從mongo數(shù)據(jù)庫中取出數(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ù)后 對interface數(shù)據(jù)進(jìn)行解析

問題

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

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

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

解決

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

看到了panic后的問題顯示

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

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

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

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

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

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

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

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

相關(guān)文章

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

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

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

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

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

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

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

    簡單講解Go程序中使用MySQL的方法

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

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

    這篇文章主要為大家詳細(xì)介紹了Go語言中內(nèi)置RPC的原理。說起?RPC?大家想到的一般是框架,Go?作為編程語言竟然還內(nèi)置了?RPC,著實(shí)讓我有些吃鯨,本文就來一起聊聊吧
    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)圖片矯正的代碼示例,文中的示例代碼簡潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-09-09
  • Golang并發(fā)操作中常見的讀寫鎖詳析

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

    Golang中的鎖機(jī)制主要包含互斥鎖和讀寫鎖互斥鎖互斥鎖是傳統(tǒng)并發(fā)程序?qū)蚕碣Y源進(jì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語言中的goroutine和channel如何協(xié)同工作

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

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

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

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

最新評論

昭平县| 北碚区| 墨脱县| 云阳县| 深州市| 白沙| 永兴县| 通化市| 运城市| 阿拉善盟| 大同县| 益阳市| 婺源县| 梅州市| 连云港市| 大同市| 济源市| 三河市| 恩平市| 衡水市| 宣化县| 师宗县| 岫岩| 景谷| 萝北县| 华坪县| 金昌市| 罗甸县| 景谷| 阿克| 二手房| 广南县| 定州市| 子洲县| 漳平市| 庆安县| 乌兰县| 江陵县| 盐津县| 信丰县| 班戈县|