<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
由於在專案中設計到了型別的判空,所以突然好奇起來,每個型別如果只是宣告,而沒有初始化,那麼預設值是多少?怎麼判斷它是不是空值?所以去整理了一下
1.常見的基本資料型別有:資料型別(int,uint,float之類的),字串(string),結構體,陣列,指標。
2.那麼他們的預設值是:
資料型別 | 預設值 |
int | 0 |
float | 0.00000 |
string | “” |
結構體 | 根據結構體內部的基礎資料型別進行初始化賦值,下面會有demo |
陣列(切片) | 空陣列 |
指標 | nil |
3.例子:
package main import ( "fmt" ) type UserInfo struct { Name string Age int Sex string Flag bool } // main函數 func main() { PrintDefault() } // 輸出預設值的函數 func PrintDefault() { var a int var b bool var c float64 var d byte var e string var f UserInfo var g *UserInfo var ip *int var bp *bool var fp *float64 var sp *string var ssp *byte var iArray []int fmt.Println("-------預設值列表--------") fmt.Printf("int的預設值為:%dn", a) fmt.Printf("bool的預設值為:%tn", b) fmt.Printf("float64的預設值為:%fn", c) fmt.Printf("byte的預設值為:%bn", d) fmt.Printf("string的預設值為:%sn", e) fmt.Printf("結構體UserInfo的預設值為:%vn", f) fmt.Printf("結構體指標UserInfo的預設值為:%vn", g) fmt.Printf("int陣列的預設值為:%vn", iArray) fmt.Printf("int指標的預設值為:%pn", ip) fmt.Printf("byte指標的預設值為:%pn", bp) fmt.Printf("string指標的預設值為:%pn", fp) fmt.Printf("float64指標的預設值為:%pn", sp) fmt.Printf("byte指標的預設值為:%pn", ssp) if ip != nil { fmt.Printf("string指標的預設值為:%dn", *ip) } }
執行結果截圖:
由上可以知道兩個點:
1.各種資料型別怎麼輸出,對應的d%,v%,s%是什麼。(大家可以看一下,後面自己本地測試輸出紀錄檔也方便)
2.瞭解各種資料的預設值,總結來說就是:資料型別是0,字元是空字元“”,結構體指標是nil,基礎資料結構指標是0x0。
值得注意的是:雖然基礎資料型別指標的輸出和結構體指標的輸出不太一樣,但是實際判空的時候,都是視為nil的。例如:
var ip *int if ip!=nil{//不會進入該邏輯,即:ip指向了0x0的時候,是視為nil的 fmt.Printf("string指標的預設值為:%dn", *ip) }
好了,那麼瞭解了各個資料型別的預設值,判空就好做多了。
直接判斷它和預設值是否一樣,是的話就認為是沒有初始化的。(這部分主要是瞭解原理,實際我們開發過程用方法2好點)
package main import ( "fmt" "reflect" ) type UserInfo struct { Name string Age int Sex string Flag bool } func main() { fmt.Println("-----------判斷型別函數實驗----------") var a int var b bool var c float64 var d byte var e string var f UserInfo var g *UserInfo var ip *int var sp *string if g == nil { fmt.Println("nil判斷成功") } var iSlice []int var iArray [2]int CheckType(a) CheckType(b) CheckType(c) CheckType(d) CheckType(e) CheckType(f) CheckType(g) CheckType(ip) CheckType(sp) CheckType(iArray) CheckType(iSlice) } // 自己寫了一個判空函數,你可以直接看判空部分的邏輯就好了。 func CheckType(args ...interface{}) { for _, arg := range args { fmt.Printf("資料型別為:%sn", reflect.TypeOf(arg).Kind().String()) //先利用反射獲取資料型別,再進入不同型別的判空邏輯 switch reflect.TypeOf(arg).Kind().String() { case "int": if arg == 0 { fmt.Println("資料為int,是空值") } case "string": if arg == "" { fmt.Println("資料為string,為空值") } else { fmt.Println("資料為string,數值為:", arg) } case "int64": if arg == 0 { fmt.Println("資料為int64,為空值") } case "uint8": if arg == false { fmt.Println("資料為bool,為false") } case "float64": if arg == 0.0 { fmt.Println("資料為float,為空值") } case "byte": if arg == 0 { fmt.Println("資料為byte,為0") } case "ptr": if arg == nil { //介面狀態下,它不認為自己是nil,所以要用反射判空 fmt.Println("資料為指標,為nil") } else { fmt.Println("資料不為空,為", arg) } //反射判空邏輯 if reflect.ValueOf(arg).IsNil() { //利用反射直接判空 fmt.Println("反射判斷:資料為指標,為nil") fmt.Println("nil:", reflect.ValueOf(nil).IsValid()) //利用反射判斷是否是有效值 } case "struct": if arg == nil { fmt.Println("資料為struct,為空值") } else { fmt.Println("資料為struct,預設有數,無法判空,只能判斷對應指標有沒有初始化,直接結構體無法判斷") } case "slice": s := reflect.ValueOf(arg) if s.Len() == 0 { fmt.Println("資料為陣列/切片,為空值") } case "array": s := reflect.ValueOf(arg) if s.Len() == 0 { fmt.Println("資料為陣列/切片,為空值") } else { fmt.Println("資料為陣列/切片,為", s.Len()) } default: fmt.Println("奇怪的資料型別") } } }
執行結果截圖:
由上可知。基本還是那句話:資料型別預設0,指標型別預設nil(介面型別下,空指標==nil會不通過,要用反射判空),字元型別為空字串“”。
利用反射包的內建函數判空. 正如上面展示的指標判空邏輯。實際上go已經有一個反射包裡面封裝了判斷
package main import ( "fmt" "reflect" ) type UserInfo struct { Name string Age int Sex string Flag bool } func main() { fmt.Println("-----------指標型別判空實驗----------") var g *UserInfo var ip *int var sp *string var iSlice []int CheckTypeByReflectNil(g) CheckTypeByReflectNil(ip) CheckTypeByReflectNil(sp) CheckTypeByReflectNil(iSlice) fmt.Println("-----------基礎型別判空實驗----------") var a int var b bool var c float64 var d byte var e string var f UserInfo CheckTypeByReflectZero(a) CheckTypeByReflectZero(b) CheckTypeByReflectZero(c) CheckTypeByReflectZero(d) CheckTypeByReflectZero(e) CheckTypeByReflectZero(f) } func CheckTypeByReflectNil(arg interface{}) { if reflect.ValueOf(arg).IsNil() { //利用反射直接判空,指標用isNil // 函數解釋:isNil() bool 判斷值是否為 nil // 如果值型別不是通道(channel)、函數、介面、map、指標或 切片時發生 panic,類似於語言層的v== nil操作 fmt.Printf("反射判斷:資料型別為%s,資料值為:%v,nil:%v n", reflect.TypeOf(arg).Kind(), reflect.ValueOf(arg), reflect.ValueOf(arg).IsValid()) } } func CheckTypeByReflectZero(arg interface{}) { if reflect.ValueOf(arg).IsZero() { //利用反射直接判空,基礎資料型別用isZero fmt.Printf("反射判斷:資料型別為%s,資料值為:%v,nil:%v n", reflect.TypeOf(arg).Kind(), reflect.ValueOf(arg), reflect.ValueOf(arg).IsValid()) } }
執行結果截圖:
到此這篇關於詳解Go語言各種常見型別的預設值和判空方法的文章就介紹到這了,更多相關Go語言常見型別的預設值和判空內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45