濮阳杆衣贸易有限公司

主頁 > 知識(shí)庫 > 解決golang 反射interface{}做零值判斷的一個(gè)重大坑

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

熱門標(biāo)簽:阿克蘇地圖標(biāo)注 評(píng)價(jià)高的400電話辦理 電話機(jī)器人軟件免費(fèi) 涿州代理外呼系統(tǒng) 百度地圖標(biāo)注后傳給手機(jī) 外呼系統(tǒng)顯本地手機(jī)號(hào) 壽光微信地圖標(biāo)注 外呼系統(tǒng)用什么卡 excel地圖標(biāo)注分布數(shù)據(jù)

在對(duì)float零值判斷時(shí)往往只需要和0做==即可,所以曾經(jīng)int和float都用==0來做對(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è)場景經(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ù)后 對(duì)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è)地方的!??!

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

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

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

您可能感興趣的文章:
  • Golang中interface{}轉(zhuǎn)為數(shù)組的操作
  • 淺談Golang 嵌套 interface 的賦值問題
  • Golang 實(shí)現(xiàn)interface類型轉(zhuǎn)string類型
  • 基于go interface{}==nil 的幾種坑及原理分析
  • golang interface判斷為空nil的實(shí)現(xiàn)代碼
  • 詳解Golang語言中的interface
  • 使用go的interface案例實(shí)現(xiàn)多態(tài)范式操作
  • go 類型轉(zhuǎn)換方式(interface 類型的轉(zhuǎn)換)

標(biāo)簽:吐魯番 蘭州 欽州 梅河口 雞西 汕頭 重慶 銅川

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《解決golang 反射interface{}做零值判斷的一個(gè)重大坑》,本文關(guān)鍵詞  解決,golang,反射,interface,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《解決golang 反射interface{}做零值判斷的一個(gè)重大坑》相關(guān)的同類信息!
  • 本頁收集關(guān)于解決golang 反射interface{}做零值判斷的一個(gè)重大坑的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    绥阳县| 彰化县| 东丽区| 东丰县| 静安区| 喀喇沁旗| 阳城县| 华宁县| 界首市| 宾川县| 红桥区| 夏津县| 伊通| 南岸区| 麦盖提县| 遂平县| 荔浦县| 普兰县| 乳源| 北辰区| 读书| 洪洞县| 高密市| 周宁县| 丰镇市| 安顺市| 丽江市| 水富县| 聊城市| 乌拉特前旗| 揭阳市| 闽清县| 若羌县| 剑阁县| 江山市| 洛浦县| 乌拉特中旗| 通州区| 武邑县| 龙陵县| 贺兰县|