在對float零值判斷時往往只需要和0做==即可,所以曾經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)
}
結果:
float 0==0: true
float -> interface{} -> float true
float -> interface -.type-> float true
但是,golang里interface{}對數據的裝箱 相比于 函數里 [入參 interface{}] 的裝箱是迥然不同的 ,比如:
func f(arg interface{}){
switch v:=arg.(type) {
case float32,float64:
fmt.Println(v==0)
}
}
func main(){
f(0.)
}
結果:
false
我擦咧,竟然是false,暫時的解決方案就是必須寫成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)
}
}
//錯誤的寫法
func f(arg interface{}){
switch v:=arg.(type) {
case float32,float64,int,int64,int32:
fmt.Println(v==0)
}
}
但是,這樣寫還是會有bug,比如傳一個float的默認值,這個場景經過仔細推敲,重現在這里:
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)
}
結果:
false
我擦咧,咋回事,還是false
最后經過仔細查找原因,原來float的相等判定的解決方案是固定的,因為計算機內部float不存在全等,所以任何兩個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)
}
}
這里還有最后一個坑會踩,那就是switch v:=arg.(type)里的v,在case路由中,如果不能精準到單路線,v還是一個interface{}
//編譯器不通過的寫法,理由是,不支持interface{}類型的v,進行float64(v)操作
func f(arg interface{}){
switch v:=arg.(type) {
case float32,float64:
r:=float64(v)
fmt.Println(math.Abs(r-0)0.0000001)
}
我擦類~
補充:golang interface{}類型轉換 bson.M 遇到莫名其妙的問題
背景
從mongo數據庫中取出數據以interface{}格式返回,解析返回的數據。
1.從mongo中取數據
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返回數據后 對interface數據進行解析

問題
問題就是出現在解析的時候報了錯

特地debug了一下queryresult的類型 發現的確是bson.M 然后他就是報錯
嘗試了各種方法,打了無數debug,并沒發現問題。
解決
最后還是在同事幫助下。。去掉了這里的斷言看看問題

看到了panic后的問題顯示

第一眼看的一頭霧水。。 bson.M not bson.M
最后想到,這是在兩個文件下的代碼 然而


一個引用了服務本地的mgo包 另一個則使用了gopath內的包所以判斷成了兩個不一樣的類型 真的是尷尬0.0
教訓總結
同一個服務用到的相同包一定要調同一個地方的!!!
同一個服務用到的相同包一定要調同一個地方的!!!
同一個服務用到的相同包一定要調同一個地方的!!!
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
您可能感興趣的文章:- Golang中interface{}轉為數組的操作
- 淺談Golang 嵌套 interface 的賦值問題
- Golang 實現interface類型轉string類型
- 基于go interface{}==nil 的幾種坑及原理分析
- golang interface判斷為空nil的實現代碼
- 詳解Golang語言中的interface
- 使用go的interface案例實現多態范式操作
- go 類型轉換方式(interface 類型的轉換)