在 go 中,对于变量声明,即使没有显示的赋初始值,go 也默认给变量赋值,具体的值取决于不同类型对应的零值。本质是 go 中的变量在创建时即分配内存,并且在内存中分配了对应类型的零值。
1
2
3
4
5
6
7
|
var a int
var b bool
var s string
fmt.Printf("%v", a) // 0
fmt.Printf("%v", b) // false
fmt.Printf("%v", s) // ""
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
var a [4]int
var b []int
var m map[string]int
var p *int
var f func()
var person Person
var c chan int
type Person struct {
Name string
age int
}
fmt.Printf("%v\n", a) // [0 0 0 0]
fmt.Printf("%v\n", b) // []
fmt.Printf("%v\n", m) // map[]
fmt.Printf("%v\n", p) // <nil>
fmt.Printf("%v\n", f) // <nil>
fmt.Printf("%v\n", person) <""0>
fmt.Printf("%v\n", c) // <nil>
|
Type |
Zero Value |
Integer |
0 |
Floating point |
0.0 |
Boolean |
false |
String |
“” |
Array: [4]int |
[0 0 0 0] |
struct |
{field: } |
Pointer |
nil |
Interface |
nil |
Slice |
nil |
Map |
nil |
Channel |
nil |
Function |
nil |
1
2
3
4
5
6
7
8
9
10
11
12
13
|
var a *int
var b *bool
var s *string
if a == nil {
fmt.Println("空值判断", "a == 0")
}
if b == nil {
fmt.Println("空值判断", "b == nil")
}
if s == nil {
fmt.Println("空值判断", "s == nil")
}
|
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
|
var a *[4]int
var b []int
var m map[string]int
var p *int
var f func()
var person *Person
var c chan int
type Person struct {
Name string
age int
}
if a == nil {
fmt.Println("空值判断", "b == nil")
}
if b == nil {
fmt.Println("空值判断", "b == nil")
}
if m == nil {
fmt.Println("空值判断", "m == nil")
}
if p == nil {
fmt.Println("空值判断", "p == nil")
}
if f == nil {
fmt.Println("空值判断", "f == nil")
}
if person == nil {
fmt.Println("空值判断", "person == nil")
}
if c == nil {
fmt.Println("空值判断", "c == nil")
}
|
总结:
在变量初始化时,go 自动赋予变量零值(0, false, “”)。
我们来看一个例子体会零值和空值的区别。
按需更新,这里指的是接口设计时,规定传来的字段一定是要更新的字段,不需要更新的字段就不要出现。举个例子:
1
2
3
4
5
6
7
|
// PUT /score
{
"id": 1,
"name": "张三",
"score": 100,
"create_time": "2021-12-12"
}
|
通过以上json,我们创建一条数据,这时该如何设计更新接口?
1
2
3
4
5
6
7
|
// POST /score
{
"id": 1,
"name": "不对,我叫李四",
"score": 0,
"create_time": ""
}
|
如上,假如规定零值字段不更新,只有非零值的字段参与更新。那么,如果用户真的想把score
字段更新为0怎么办,实际上,零值和空值就产生了歧义。
1
2
3
4
5
|
// POST /score
{
"id": 1,
"name": "我叫李四"
}
|
所以为了避免歧义,我们规定不更新的字段禁止出现在json中。同样的,在json转为go中的结构体时,我们也只能通过指针来接收:
1
2
3
4
5
6
|
type UpdateScore struct{
Id int
Name *string
Score *int
CreateTime *string
}
|