最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

詳解Go語言各種常見類型的默認(rèn)值和判空方法

2023-07-07 23:32 作者:哈市飛劍  | 我要投稿

起因(解決的問題)

由于在項目中設(shè)計到了類型的判空,所以突然好奇起來,每個類型如果只是聲明,而沒有初始化,那么默認(rèn)值是多少?怎么判斷它是不是空值?所以去整理了一下

基本類型的默認(rèn)值

1.常見的基本數(shù)據(jù)類型有:數(shù)據(jù)類型(int,uint,float之類的),字符串(string),結(jié)構(gòu)體,數(shù)組,指針。

2.那么他們的默認(rèn)值是:

數(shù)據(jù)類型

默認(rèn)值

int

0

float

0.00000

string

“”

結(jié)構(gòu)體

根據(jù)結(jié)構(gòu)體內(nèi)部的基礎(chǔ)數(shù)據(jù)類型進(jìn)行初始化賦值,下面會有demo

數(shù)組(切片)

空數(shù)組

指針

nil

3.例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package main
??
import (
????"fmt"
)
??
type UserInfo struct {
????Name string
????Age? int
????Sex? string
????Flag bool
}
??
// main函數(shù)
func main() {
????PrintDefault()
}
??
// 輸出默認(rèn)值的函數(shù)
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("-------默認(rèn)值列表--------")
????fmt.Printf("int的默認(rèn)值為:%d\n", a)
????fmt.Printf("bool的默認(rèn)值為:%t\n", b)
????fmt.Printf("float64的默認(rèn)值為:%f\n", c)
????fmt.Printf("byte的默認(rèn)值為:%b\n", d)
????fmt.Printf("string的默認(rèn)值為:%s\n", e)
????fmt.Printf("結(jié)構(gòu)體UserInfo的默認(rèn)值為:%v\n", f)
????fmt.Printf("結(jié)構(gòu)體指針UserInfo的默認(rèn)值為:%v\n", g)
????fmt.Printf("int數(shù)組的默認(rèn)值為:%v\n", iArray)
????fmt.Printf("int指針的默認(rèn)值為:%p\n", ip)
????fmt.Printf("byte指針的默認(rèn)值為:%p\n", bp)
????fmt.Printf("string指針的默認(rèn)值為:%p\n", fp)
????fmt.Printf("float64指針的默認(rèn)值為:%p\n", sp)
????fmt.Printf("byte指針的默認(rèn)值為:%p\n", ssp)
????if ip != nil {
????????fmt.Printf("string指針的默認(rèn)值為:%d\n", *ip)
????}
}

運(yùn)行結(jié)果截圖:

由上可以知道兩個點(diǎn):

1.各種數(shù)據(jù)類型怎么輸出,對應(yīng)的d%,v%,s%是什么。(大家可以看一下,后面自己本地測試輸出日志也方便)

2.了解各種數(shù)據(jù)的默認(rèn)值,總結(jié)來說就是:數(shù)據(jù)類型是0,字符是空字符“”,結(jié)構(gòu)體指針是nil,基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)指針是0x0。

值得注意的是:雖然基礎(chǔ)數(shù)據(jù)類型指針的輸出和結(jié)構(gòu)體指針的輸出不太一樣,但是實際判空的時候,都是視為nil的。例如:

1
2
3
4
var ip *int
if ip!=nil{//不會進(jìn)入該邏輯,即:ip指向了0x0的時候,是視為nil的
????????fmt.Printf("string指針的默認(rèn)值為:%d\n", *ip)
????}

好了,那么了解了各個數(shù)據(jù)類型的默認(rèn)值,判空就好做多了。

判斷是否初始化(判空)

方法1:

直接判斷它和默認(rèn)值是否一樣,是的話就認(rèn)為是沒有初始化的。(這部分主要是了解原理,實際我們開發(fā)過程用方法2好點(diǎn))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package main
??
import (
????"fmt"
????"reflect"
)
??
type UserInfo struct {
????Name string
????Age? int
????Sex? string
????Flag bool
}
??
func main() {
????fmt.Println("-----------判斷類型函數(shù)實驗----------")
????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)
}
??
// 自己寫了一個判空函數(shù),你可以直接看判空部分的邏輯就好了。
func CheckType(args ...interface{}) {
????for _, arg := range args {
????????fmt.Printf("數(shù)據(jù)類型為:%s\n", reflect.TypeOf(arg).Kind().String()) //先利用反射獲取數(shù)據(jù)類型,再進(jìn)入不同類型的判空邏輯
????????switch reflect.TypeOf(arg).Kind().String() {
????????case "int":
????????????if arg == 0 {
????????????????fmt.Println("數(shù)據(jù)為int,是空值")
????????????}
????????case "string":
????????????if arg == "" {
????????????????fmt.Println("數(shù)據(jù)為string,為空值")
????????????} else {
????????????????fmt.Println("數(shù)據(jù)為string,數(shù)值為:", arg)
????????????}
????????case "int64":
????????????if arg == 0 {
????????????????fmt.Println("數(shù)據(jù)為int64,為空值")
????????????}
????????case "uint8":
????????????if arg == false {
????????????????fmt.Println("數(shù)據(jù)為bool,為false")
????????????}
????????case "float64":
????????????if arg == 0.0 {
????????????????fmt.Println("數(shù)據(jù)為float,為空值")
????????????}
????????case "byte":
????????????if arg == 0 {
????????????????fmt.Println("數(shù)據(jù)為byte,為0")
????????????}
????????case "ptr":
????????????if arg == nil { //接口狀態(tài)下,它不認(rèn)為自己是nil,所以要用反射判空
????????????????fmt.Println("數(shù)據(jù)為指針,為nil")
????????????} else {
????????????????fmt.Println("數(shù)據(jù)不為空,為", arg)
????????????}
????????????//反射判空邏輯
????????????if reflect.ValueOf(arg).IsNil() { //利用反射直接判空
????????????????fmt.Println("反射判斷:數(shù)據(jù)為指針,為nil")
????????????????fmt.Println("nil:", reflect.ValueOf(nil).IsValid()) //利用反射判斷是否是有效值
????????????}
????????case "struct":
????????????if arg == nil {
????????????????fmt.Println("數(shù)據(jù)為struct,為空值")
????????????} else {
????????????????fmt.Println("數(shù)據(jù)為struct,默認(rèn)有數(shù),無法判空,只能判斷對應(yīng)指針有沒有初始化,直接結(jié)構(gòu)體無法判斷")
????????????}
????????case "slice":
????????????s := reflect.ValueOf(arg)
????????????if s.Len() == 0 {
????????????????fmt.Println("數(shù)據(jù)為數(shù)組/切片,為空值")
????????????}
????????case "array":
????????????s := reflect.ValueOf(arg)
????????????if s.Len() == 0 {
????????????????fmt.Println("數(shù)據(jù)為數(shù)組/切片,為空值")
????????????} else {
????????????????fmt.Println("數(shù)據(jù)為數(shù)組/切片,為", s.Len())
????????????}
????????default:
????????????fmt.Println("奇怪的數(shù)據(jù)類型")
????????}
????}
}

運(yùn)行結(jié)果截圖:

由上可知。基本還是那句話:數(shù)據(jù)類型默認(rèn)0,指針類型默認(rèn)nil(接口類型下,空指針==nil會不通過,要用反射判空),字符類型為空字符串“”。

方式2:

利用反射包的內(nèi)置函數(shù)判空. 正如上面展示的指針判空邏輯。實際上go已經(jīng)有一個反射包里面封裝了判斷

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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("-----------基礎(chǔ)類型判空實驗----------")
????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
????????// 函數(shù)解釋:isNil() bool??? 判斷值是否為 nil
????????// 如果值類型不是通道(channel)、函數(shù)、接口、map、指針或 切片時發(fā)生 panic,類似于語言層的v== nil操作
????????fmt.Printf("反射判斷:數(shù)據(jù)類型為%s,數(shù)據(jù)值為:%v,nil:%v \n",
????????????reflect.TypeOf(arg).Kind(), reflect.ValueOf(arg), reflect.ValueOf(arg).IsValid())
????}
}
??
func CheckTypeByReflectZero(arg interface{}) {
????if reflect.ValueOf(arg).IsZero() { //利用反射直接判空,基礎(chǔ)數(shù)據(jù)類型用isZero
????????fmt.Printf("反射判斷:數(shù)據(jù)類型為%s,數(shù)據(jù)值為:%v,nil:%v \n",
????????????reflect.TypeOf(arg).Kind(), reflect.ValueOf(arg), reflect.ValueOf(arg).IsValid())
????}
}

運(yùn)行結(jié)果截圖:


詳解Go語言各種常見類型的默認(rèn)值和判空方法的評論 (共 條)

分享到微博請遵守國家法律
南靖县| 齐河县| 高碑店市| 廊坊市| 金沙县| 方山县| 邓州市| 云安县| 三亚市| 红安县| 阿克苏市| 洛宁县| 日喀则市| 平乡县| 朝阳市| 衡阳县| 方城县| 蒲城县| 千阳县| 渭南市| 柳河县| 航空| 扶余县| 凤城市| 翁牛特旗| 临桂县| 苍溪县| 赞皇县| 荔浦县| 封开县| 锦州市| 章丘市| 台北县| 夏邑县| 马公市| 开阳县| 德钦县| 绥阳县| 神木县| 东安县| 瑞丽市|