Golang usa protobuf en el entorno de Windows

Introducción a Protobuf

La biblioteca de serialización se usa a menudo en transmisión de red, RPC, acceso a bases de datos y otros entornos. Su rendimiento afecta directamente el rendimiento de todo el producto, por lo que es necesario que aprendamos y dominemos algunas bibliotecas de serialización excelentes.

protobuf es un lenguaje de lenguaje de descripción de datos desarrollado por Google, que puede serializar datos estructurados y puede usarse para almacenamiento de datos, protocolo de comunicación, etc. La versión oficial es compatible con Go, C ++, Java, Python y la versión comunitaria admite más lenguajes.

En comparación con JSON y XML, tiene las siguientes ventajas:

  1. conciso
  2. Tamaño pequeño: una décima parte de json, una vigésima parte del formato xml, una décima parte de la serialización binaria
  3. Velocidad rápida: la velocidad de análisis es 20 ~ 100 veces más rápida que XML
  4. Usando el compilador de Protobuf, puede generar códigos de acceso a datos que son más fáciles de usar en la programación
  5. Mejor compatibilidad, un principio del diseño de Protobuf es poder soportar bien la compatibilidad hacia abajo o hacia arriba
  6. Después de que protobuf serializa los datos en binario, el espacio ocupado es bastante pequeño, básicamente solo se reserva la parte de datos, y xml y json tendrán la estructura del mensaje en los datos;

Documento oficial

Configuración IDE

De forma predeterminada, IDE goland no admite el tipo de archivo de protocolo protobuf ".proto". Para escribir el código en el archivo proto de manera más rápida y eficiente, introduciremos un complemento para admitirlo. El complemento admite la palabra clave mensajes de error de sintaxis y resaltado.

1. Archivo-> Configuración-> Complementos-> Ingrese al soporte de protobuf-> instalar y reinicie el IDE

Inserte la descripción de la imagen aquí
2. Archivo-> Configuración-> Editor-> Tipos de archivo, busque Protobuf, regístrese para admitir * .proto
Inserte la descripción de la imagen aquí

Configuración del compilador


Protobuffer pertenece a un acuerdo multiplataforma y entre idiomas. Tiene su propio protocolo de compilación , que es el compilador de Protobuf para
descargar el último paquete comprimido. Después de la descompresión, coloque el programa protocol.exe en el directorio bin de gopath, preferiblemente el directorio bin de gopath Agregar a las variables de entorno del sistema Enlace de
descarga: https://github.com/protocolbuffers/protobuf/releases
Inserte la descripción de la imagen aquí
Prueba:

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

Instale el archivo de la biblioteca protobuf:

go get github.com/golang/protobuf/proto

Instale el complemento goprotobuf (complemento del compilador de Protobuf para la versión go):

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

Ejemplo

Estructura de directorios:
Inserte la descripción de la imagen aquí

Nota:
El archivo de formato proto que queremos escribir se almacena en el directorio protos

syntax = "proto3";

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

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

}

Generar .pb.go

Vaya al directorio protos para ejecutar

protoc --go_out=. *.proto

Los archivos generados se almacenan en el directorio pb

// 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
}

La función principal es la lógica empresarial principal. Aquí hay una demostración de serialización y deserialización:

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)
}

Supongo que te gusta

Origin blog.csdn.net/csdniter/article/details/112209397
Recomendado
Clasificación