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

简介: Go语言开发小技巧&易错点100例(八)


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

  • JSON Marshal和Proto Marshal在Protobuf Message结构体上使用的不同【易】
  • channel方式代替time.Sleep()方法【技】

正文开始

JSON Marshal和Proto Marshal在gRPC Message上使用的不同

我们先定义一个Proto Buffer文件,内容为一个Message,有两个属性,其中一个属性为string类型,一个为onef类型:

syntax = "proto3";
option go_package = "/test";
package cmd;
message UserInfo {
  string name = 1;
  oneof address {
    string school_addr = 2;
    string home_addr = 3;
  }
}

接下来我们编译成pb.go文件

protoc -I=. --go_out=.. ./hello.proto

具体编译后的结构体:

type UserInfo struct {
  state         protoimpl.MessageState
  sizeCache     protoimpl.SizeCache
  unknownFields protoimpl.UnknownFields
  Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
  // Types that are assignable to Address:
  //  *UserInfo_SchoolAddr
  //  *UserInfo_HomeAddr
  Address isUserInfo_Address `protobuf_oneof:"address"`
}
// ...
type UserInfo_SchoolAddr struct {
  SchoolAddr string `protobuf:"bytes,2,opt,name=school_addr,json=schoolAddr,proto3,oneof"`
}
// ...
type UserInfo_HomeAddr struct {
  HomeAddr string `protobuf:"bytes,3,opt,name=home_addr,json=homeAddr,proto3,oneof"`
}

然后我们写两个测试方法:

方法一:JSON Marshl的方式序列化结构体

func TestJSONMarshal(t *testing.T) {
   u := UserInfo{
      Name:    "zs",
      Address: &UserInfo_HomeAddr{HomeAddr: "Beijing"},
   }
   marshal, _ := json.Marshal(u)
   fmt.Println(string(marshal))
   var u2 UserInfo
   _ = json.Unmarshal(marshal, &u2)
   fmt.Println(u2)
}

结果:

方法二:Proto Marshal的方式序列化结构体

func TestProtoMarshal(t *testing.T) {
   u := UserInfo{
      Name:    "zs",
      Address: &UserInfo_HomeAddr{HomeAddr: "Beijing"},
   }
   marshal, _ := proto.Marshal(u)
   fmt.Println(string(marshal))
   var u2 UserInfo
   _ = proto.Unmarshal(marshal, u2)
   fmt.Println(u2)
}

结果:

对比上述的结果,我们会发现有些不同

  • 序列化后的内容不同,JSON Marshal序列化后的内容可读性较高但是内容占用空间多
  • 反序列化时Proto Marshal的方式能够自动识别oneof类型的属性

因此我们得出结论,在直接序列化Message时最好使用Proto Marshal的方式进行序列化,防止特殊的属性不能够识别,而且该序列化的方式更加节省空间,缺点则是序列化的结果可读性不高。

channel方式代替time.Sleep()方法

最新发现的新操作,直接上代码:

func TestSleep(t *testing.T) {
    <-time.After(time.Second) // 相当于time.Sleep(time.Second)
}

本期到此结束~

相关文章
|
6月前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
554 4
|
8月前
|
数据采集 数据挖掘 测试技术
Go与Python爬虫实战对比:从开发效率到性能瓶颈的深度解析
本文对比了Python与Go在爬虫开发中的特点。Python凭借Scrapy等框架在开发效率和易用性上占优,适合快速开发与中小型项目;而Go凭借高并发和高性能优势,适用于大规模、长期运行的爬虫服务。文章通过代码示例和性能测试,分析了两者在并发能力、错误处理、部署维护等方面的差异,并探讨了未来融合发展的趋势。
839 0
|
6月前
|
JavaScript 前端开发 Java
【GoWails】Go做桌面应用开发?本篇文章带你上手Wails框架!一步步带你玩明白前后端双端的数据绑定!
wails是一个可以让你使用Go和Web技术编写桌面应用的项目 可以将它看作Go的快并且轻量级的Electron替代品。可以使用Go的功能,并结合现代化UI完成桌面应用程序的开发
1267 6
|
6月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
343 2
|
8月前
|
Cloud Native 安全 Java
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
516 1
|
8月前
|
Cloud Native Go API
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
544 0
|
8月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
370 0
|
8月前
|
Cloud Native Java 中间件
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
421 0
|
8月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
464 0
|
存储 缓存 安全
Go 语言中的 Sync.Map 详解:并发安全的 Map 实现
`sync.Map` 是 Go 语言中用于并发安全操作的 Map 实现,适用于读多写少的场景。它通过两个底层 Map(`read` 和 `dirty`)实现读写分离,提供高效的读性能。主要方法包括 `Store`、`Load`、`Delete` 等。在大量写入时性能可能下降,需谨慎选择使用场景。

热门文章

最新文章

下一篇
开通oss服务