Golang uses protobuf in windows environment

Introduction to Protobuf

The serialization library is often used in network transmission, RPC, database access and other environments. Its performance directly affects the performance of the entire product, so it is necessary for us to further learn and master some excellent serialization libraries.

protobuf is a data description language language developed by Google, which can serialize structured data and can be used for data storage, communication protocol, etc. The official version supports Go, C++, Java, Python, and the community version supports more languages.

Compared with JSON and XML, it has the following advantages:

  1. concise
  2. Small size: one-tenth of json, one-twentieth of xml format, one-tenth of binary serialization
  3. Fast speed: parsing speed is 20 ~ 100 times faster than XML
  4. Using Protobuf's compiler, you can generate data access codes that are easier to use in programming
  5. Better compatibility, one of the principles of Protobuf design is to be able to support downward or upward compatibility well
  6. After protobuf serializes the data into binary, the space occupied is quite small, basically only the data part is reserved, and xml and json will have message structure in the data;

Official document

IDE settings

By default, IDE goland does not support the protobuf protocol file type ".proto". In order to write the code in the proto file faster and more efficiently, we will introduce a plug-in to support it. The plug-in supports keyword highlighting and syntax error prompts.

1. File->Settings->Plugins->Enter protobuf support->install, and restart the IDE

Insert picture description here
2. File->Settings->Editor->File Types, find Protobuf, register to support *.proto
Insert picture description here

Compiler configuration


Protobuffer belongs to a cross-platform, cross-language agreement. It has its own compiler protoc, which is the Protobuf compiler to
download the latest compressed package. After decompression, put the protoc.exe program in the bin directory of gopath, preferably the bin directory of gopath Add to the system environment variables
Download link : https://github.com/protocolbuffers/protobuf/releases
Insert picture description here
Test:

终端输入`protoc --version` 显示版本即代表安装成功
或
执行 `protoc -h`   正常输出 相关指令 没有报任何error,为安装成功

Install the protobuf library file:

go get github.com/golang/protobuf/proto

Install goprotobuf plugin (Protobuf compiler plugin for go version):

go get github.com/golang/protobuf/protoc-gen-go

Example

Directory Structure:
Insert picture description here

Note:
The proto format file that we want to write is stored in the protos directory

syntax = "proto3";

// 新版的proto编译器都要求文件中标注编译后文件的存储位置
// 即生成的.pb.go文件会存放在../pb中,并和该文件名保持一致
// test.proto => test.pb.go
option go_package = "../pb";

message Person {
    
    
    string Name = 1;
    int32 Age = 2;

}

Generate .pb.go

Go to the protos directory to execute

protoc --go_out=. *.proto

The generated files are stored in the pb directory

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.25.0
// 	protoc        v3.14.0
// source: test.proto

package pb

import (
	proto "github.com/golang/protobuf/proto"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// This is a compile-time assertion that a sufficiently up-to-date version
// of the legacy proto package is being used.
const _ = proto.ProtoPackageIsVersion4

type Person struct {
    
    
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"`
	Age  int32  `protobuf:"varint,2,opt,name=Age,proto3" json:"Age,omitempty"`
}

func (x *Person) Reset() {
    
    
	*x = Person{
    
    }
	if protoimpl.UnsafeEnabled {
    
    
		mi := &file_test_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *Person) String() string {
    
    
	return protoimpl.X.MessageStringOf(x)
}

func (*Person) ProtoMessage() {
    
    }

func (x *Person) ProtoReflect() protoreflect.Message {
    
    
	mi := &file_test_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
    
    
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
    
    
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Person.ProtoReflect.Descriptor instead.
func (*Person) Descriptor() ([]byte, []int) {
    
    
	return file_test_proto_rawDescGZIP(), []int{
    
    0}
}

func (x *Person) GetName() string {
    
    
	if x != nil {
    
    
		return x.Name
	}
	return ""
}

func (x *Person) GetAge() int32 {
    
    
	if x != nil {
    
    
		return x.Age
	}
	return 0
}

var File_test_proto protoreflect.FileDescriptor

var file_test_proto_rawDesc = []byte{
    
    
	0x0a, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2e, 0x0a, 0x06,
	0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01,
	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x41, 0x67,
	0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x41, 0x67, 0x65, 0x42, 0x07, 0x5a, 0x05,
	0x2e, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_test_proto_rawDescOnce sync.Once
	file_test_proto_rawDescData = file_test_proto_rawDesc
)

func file_test_proto_rawDescGZIP() []byte {
    
    
	file_test_proto_rawDescOnce.Do(func() {
    
    
		file_test_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_proto_rawDescData)
	})
	return file_test_proto_rawDescData
}

var file_test_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_test_proto_goTypes = []interface{
    
    }{
    
    
	(*Person)(nil), // 0: Person
}
var file_test_proto_depIdxs = []int32{
    
    
	0, // [0:0] is the sub-list for method output_type
	0, // [0:0] is the sub-list for method input_type
	0, // [0:0] is the sub-list for extension type_name
	0, // [0:0] is the sub-list for extension extendee
	0, // [0:0] is the sub-list for field type_name
}

func init() {
    
     file_test_proto_init() }
func file_test_proto_init() {
    
    
	if File_test_proto != nil {
    
    
		return
	}
	if !protoimpl.UnsafeEnabled {
    
    
		file_test_proto_msgTypes[0].Exporter = func(v interface{
    
    }, i int) interface{
    
    } {
    
    
			switch v := v.(*Person); i {
    
    
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{
    
    }
	out := protoimpl.TypeBuilder{
    
    
		File: protoimpl.DescBuilder{
    
    
			GoPackagePath: reflect.TypeOf(x{
    
    }).PkgPath(),
			RawDescriptor: file_test_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_test_proto_goTypes,
		DependencyIndexes: file_test_proto_depIdxs,
		MessageInfos:      file_test_proto_msgTypes,
	}.Build()
	File_test_proto = out.File
	file_test_proto_rawDesc = nil
	file_test_proto_goTypes = nil
	file_test_proto_depIdxs = nil
}

The main function is the main business logic. Here is a demonstration of serialization and deserialization:

package main

import (
	"fmt"
	"grpc_learn/pb"

	"github.com/golang/protobuf/proto"
)

func main() {
    
    
	p1 := pb.Person{
    
    
		Name: "Jack",
		Age:  34,
	}
	fmt.Printf("person: %+v\n", p1)
	buffer, _ := proto.Marshal(&p1)
	fmt.Println("序列化person: ", buffer)
	var person pb.Person
	proto.Unmarshal(buffer, &person)
	fmt.Printf("反序列化person: %+v\n", person)
}

Guess you like

Origin blog.csdn.net/csdniter/article/details/112209397