前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Go语言开发小技巧&易错点100例(八)

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

原创
作者头像
闫同学
发布2023-10-03 20:03:22
发布2023-10-03 20:03:22
2020
举报
文章被收录于专栏:扯编程的淡

往期回顾:

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

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

正文开始

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

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

代码语言:go
复制
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文件

代码语言:shell
复制
protoc -I=. --go_out=.. ./hello.proto

具体编译后的结构体:

代码语言:go
复制
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的方式序列化结构体

代码语言:go
复制
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)
}

结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jUlVgySx-1690033591008)(Go语言开发小技巧&易错点100例(八).assets/image-20230722211709041.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jUlVgySx-1690033591008)(Go语言开发小技巧&易错点100例(八).assets/image-20230722211709041.png)]

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

代码语言:go
复制
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)
}

结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i5L9h37K-1690033591011)(Go语言开发小技巧&易错点100例(八).assets/image-20230722211642116.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i5L9h37K-1690033591011)(Go语言开发小技巧&易错点100例(八).assets/image-20230722211642116.png)]

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

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

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

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

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

代码语言:go
复制
func TestSleep(t *testing.T) {

    <-time.After(time.Second) // 相当于time.Sleep(time.Second)

}

本期到此结束~

我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JSON Marshal和Proto Marshal在gRPC Message上使用的不同
  • channel方式代替time.Sleep()方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档