• Go语言开发小技巧&易错点100例(三)


    这么快就第三期了,算下来这期包括前几期我的《Go语言开发小技巧&易错点100例》已经凑够了15个!任务完成率15%!继续加油!

    往期回顾

    本期看点(技巧类用【技】表示,易错点用【易】表示)

    (1)Go omitempty关键字【技】

    (2)Go 进行JSON Marshal序列化时需要注意的问题【易】

    (3)Go iota关键字【技】

    下面是正文

    1 Go omitempty关键字【技】

    大家在将Go语言里面的结构体类型转化为JSON数据类型时有没有过这样的需求:

    当结构体有多个字段时,仅赋值部分字段,让其余字段都为空,并且在JSON Marshal时不序列化为空的字段

    代码表示:

    type Student struct {
       Id   int    `json:"id"`
       Name string `json:"name"`
       Age  int    `json:"age"`
    }
    
    func main() {
       // 只赋值Id、Name,不赋值Age属性
       stu := Student{
          Id:   1,
          Name: "zs",
       }
       bytes, _ := json.Marshal(stu)
       fmt.Println(string(bytes))
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    运行结果:

    {"id":1,"name":"zs","age":0}
    
    • 1

    但是我们想要的结果是

    {"id":1,"name":"zs"}
    
    • 1

    这个时候,就使用需要使用到这个关键字:omitempty,该关键字作用:

    • 基本类型的默认值会被缺省(omit),除了具有默认长度的数组。
    • 指针类型为 nil 时会被缺省(omit)。

    接下来我们就来实验下:

    type Student struct {
       Id      int       `json:"id,omitempty"`
       Name    string    `json:"name,omitempty"`
       Age     int       `json:"age,omitempty"`
       Address *string   `json:"address,omitempty"`
       Like    []string  `json:"list,omitempty"`
       Love    [1]string `json:"love,omitempty"`
    }
    
    func main() {
       // 只赋值Id、Name,不赋值Age属性
       stu := Student{
          Id:   1,
          Name: "zs",
       }
       bytes, _ := json.Marshal(stu)
       fmt.Println(string(bytes))
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    输出的结果:

    {"id":1,"name":"zs","love":[""]}
    
    • 1

    2 Go JSON Marshal需要注意的问题【易】

    Go语言有一个约定,就是首字母大写的属性或函数才能够外部可见,外部指的是包外部,除此之外在JSON Marshal中也需要用到类似的约定:只有结构体的属性属于外部可见时才能够进行JSON序列化。

    直接上代码:

    type Object struct {
       name   string `json:"name"`
       method string `json:"method"`
    }
    
    func main() {
       obj := Object{
          name: "zs",
          method: "play",
       }
       bytes, _ := json.Marshal(obj)
       fmt.Println(string(bytes))
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    打印结果:

    {}
    
    • 1

    解决方式就是将结构体的属性名改成大写,之后就可以了:

    type Object struct {
    	Name   string `json:"name"`
    	Method string `json:"method"`
    }
    
    • 1
    • 2
    • 3
    • 4

    3 Go iota关键字【技】

    概念:iota是go语言的常量计数器,只能在常量的表达式中使用,多用于代替枚举类型。

    注意点:

    (1)iota在const关键字中定义,默认为0,并且以同一个const中多个iota只能默认为0一次。

    (2)const中每新增一行常量声明将使iota按规则计数一次。

    使用方式:

    const (
       i1 = iota
       i2
       _ //丢弃该值
       i4
    )
    
    const (
       n1 = iota * 10
       n2
       n3
    )
    
    func main() {
       fmt.Println(i1)
       fmt.Println(i2)
       fmt.Println(i4)
    
       fmt.Println(n1)
       fmt.Println(n2)
       fmt.Println(n3)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    我们看看time包源码中对iota关键字的使用:

    ......
    // A Month specifies a month of the year (January = 1, ...).
    type Month int
    
    const (
       January Month = 1 + iota
       February
       March
       April
       May
       June
       July
       August
       September
       October
       November
       December
    )
    ......
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    如果同一个const中定义了多个iota会怎样:

    const (
       i1 = iota
       i2
    
       n1 = iota * 10
       n2
       n3
    )
    
    func main() {
       fmt.Println(i1)
       fmt.Println(i2)
    
       fmt.Println(n1)
       fmt.Println(n2)
       fmt.Println(n3)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    打印结果:

    0
    1
    20
    30
    40
    
    • 1
    • 2
    • 3
    • 4
    • 5

    好嘞,今天的分享就先到这里,欢迎大家关注我,会持续更新~

  • 相关阅读:
    C语言——动态内存管理详解(内存结构、动态内存函数、易错题、柔性数组)
    Oauth2认证及Spring Security Oauth2授权码模式
    css 写带三角形的对话框,空心的三角形边框
    【架构】 第7章 主从复制高可用Redis集群
    【C语言进阶】文件操作(二)
    Go的闭包理解
    软考重点10 知识产权
    备战数学建模30-回归分析2
    私有git仓库只支持http情况下go mod tidy 和 go get 默认走https的问题处理 GOINSECURE
    基于区块链与联邦学习技术的数据交易平台
  • 原文地址:https://blog.csdn.net/Mr_YanMingXin/article/details/128167507