go protobuf

go protobuf

安装protoc工具

protoc工具用来将.proto文件转化为自己使用的语言格式。

首先去https://github.com/protocolbuffers/protobuf/releases下载protobuf的编译器protoc,windows上可以直接下到exe文件(linux则需要编译),最后将下载好的可执行文件拷贝到$GOPATH的bin目录下($GOPATH/bin目录最好添加到系统环境变量里)

linux环境,下载protoc源码,下载地址,我选择如图的安装包,可以不需要再编译,直接将bin添加到环境变量中或者将bin/protoc 软链接到/usr/bin下。

protobuf插件

go语言相关的有两个插件gogoprotobuf和goprotobuf(官方出品)

我这块选择gogoprotobuf(比官方感觉更好),同样也兼容官方

go get github.com/gogo/protobuf/protoc-gen-gofast

  编写test.proto文件

syntax="proto3"; //版本号
package main;  //包名
enum ClassName{   //枚举
    class1=0;  //标号 必须从 0开始
    class2=1;
    class3=2;
}
message Student{ //消息,对应于Go的结构体
  string name=1; //1:标号,唯一 即可(相当于数据库中的Id,不一定要从1 ,2的顺序依次排列。)
  int32 age=2;  //必须指定整型的范围,如int32,int64
  string address=3;
  ClassName cn=4;
}
message Students{
   repeated Student person=1;  // repeated 修饰,相当于Go中切片
   string school=2;
}

 根据test.proto自动生成go源码test.pb.go

protoc --gofast_out=. .	est.proto

  

// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: test.proto

package main

import (
	fmt "fmt"
	proto "github.com/gogo/protobuf/proto"
	io "io"
	math "math"
	math_bits "math/bits"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
//const _ = proto.ProtoPackageIsVersion3 // 注释掉此行,否则编译报错

type ClassName int32

const (
	ClassName_class1 ClassName = 0
	ClassName_class2 ClassName = 1
	ClassName_class3 ClassName = 2
)

var ClassName_name = map[int32]string{
	0: "class1",
	1: "class2",
	2: "class3",
}

var ClassName_value = map[string]int32{
	"class1": 0,
	"class2": 1,
	"class3": 2,
}

func (x ClassName) String() string {
	return proto.EnumName(ClassName_name, int32(x))
}

func (ClassName) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_c161fcfdc0c3ff1e, []int{0}
}

type Student struct {
	Name                 string    `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	Age                  int32     `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
	Address              string    `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"`
	Cn                   ClassName `protobuf:"varint,4,opt,name=cn,proto3,enum=main.ClassName" json:"cn,omitempty"`
	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
	XXX_unrecognized     []byte    `json:"-"`
	XXX_sizecache        int32     `json:"-"`
}

func (m *Student) Reset()         { *m = Student{} }
func (m *Student) String() string { return proto.CompactTextString(m) }
func (*Student) ProtoMessage()    {}
func (*Student) Descriptor() ([]byte, []int) {
	return fileDescriptor_c161fcfdc0c3ff1e, []int{0}
}
func (m *Student) XXX_Unmarshal(b []byte) error {
	return m.Unmarshal(b)
}
func (m *Student) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	if deterministic {
		return xxx_messageInfo_Student.Marshal(b, m, deterministic)
	} else {
		b = b[:cap(b)]
		n, err := m.MarshalToSizedBuffer(b)
		if err != nil {
			return nil, err
		}
		return b[:n], nil
	}
}
func (m *Student) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Student.Merge(m, src)
}
func (m *Student) XXX_Size() int {
	return m.Size()
}
func (m *Student) XXX_DiscardUnknown() {
	xxx_messageInfo_Student.DiscardUnknown(m)
}

var xxx_messageInfo_Student proto.InternalMessageInfo

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

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

func (m *Student) GetAddress() string {
	if m != nil {
		return m.Address
	}
	return ""
}

func (m *Student) GetCn() ClassName {
	if m != nil {
		return m.Cn
	}
	return ClassName_class1
}

type Students struct {
	Person               []*Student `protobuf:"bytes,1,rep,name=person,proto3" json:"person,omitempty"`
	School               string     `protobuf:"bytes,2,opt,name=school,proto3" json:"school,omitempty"`
	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
	XXX_unrecognized     []byte     `json:"-"`
	XXX_sizecache        int32      `json:"-"`
}

func (m *Students) Reset()         { *m = Students{} }
func (m *Students) String() string { return proto.CompactTextString(m) }
func (*Students) ProtoMessage()    {}
func (*Students) Descriptor() ([]byte, []int) {
	return fileDescriptor_c161fcfdc0c3ff1e, []int{1}
}
func (m *Students) XXX_Unmarshal(b []byte) error {
	return m.Unmarshal(b)
}
func (m *Students) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	if deterministic {
		return xxx_messageInfo_Students.Marshal(b, m, deterministic)
	} else {
		b = b[:cap(b)]
		n, err := m.MarshalToSizedBuffer(b)
		if err != nil {
			return nil, err
		}
		return b[:n], nil
	}
}
func (m *Students) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Students.Merge(m, src)
}
func (m *Students) XXX_Size() int {
	return m.Size()
}
func (m *Students) XXX_DiscardUnknown() {
	xxx_messageInfo_Students.DiscardUnknown(m)
}

var xxx_messageInfo_Students proto.InternalMessageInfo

func (m *Students) GetPerson() []*Student {
	if m != nil {
		return m.Person
	}
	return nil
}

func (m *Students) GetSchool() string {
	if m != nil {
		return m.School
	}
	return ""
}

func init() {
	proto.RegisterEnum("main.ClassName", ClassName_name, ClassName_value)
	proto.RegisterType((*Student)(nil), "main.Student")
	proto.RegisterType((*Students)(nil), "main.Students")
}

func init() { proto.RegisterFile("test.proto", fileDescriptor_c161fcfdc0c3ff1e) }

var fileDescriptor_c161fcfdc0c3ff1e = []byte{
	// 230 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x3c, 0x90, 0x3d, 0x4e, 0xc4, 0x30,
	0x10, 0x85, 0x77, 0x92, 0x90, 0x25, 0x83, 0x00, 0x6b, 0x0a, 0xe4, 0x2a, 0x44, 0x2b, 0x21, 0x45,
	0x14, 0x41, 0x64, 0x6f, 0x00, 0x15, 0x0d, 0x85, 0x39, 0x81, 0x49, 0x2c, 0x7e, 0xb4, 0xb1, 0x57,
	0x19, 0x73, 0x17, 0x8e, 0x44, 0xc9, 0x11, 0x50, 0xb8, 0x08, 0x8a, 0xf1, 0xa6, 0xfb, 0x3e, 0x3d,
	0xfb, 0xcd, 0x68, 0x10, 0xbd, 0x61, 0xdf, 0xec, 0x47, 0xe7, 0x1d, 0x65, 0x83, 0x7e, 0xb3, 0x9b,
	0x77, 0x5c, 0x3f, 0xf9, 0x8f, 0xde, 0x58, 0x4f, 0x84, 0x99, 0xd5, 0x83, 0x91, 0x50, 0x41, 0x5d,
	0xa8, 0xc0, 0x24, 0x30, 0xd5, 0x2f, 0x46, 0x26, 0x15, 0xd4, 0x47, 0x6a, 0x46, 0x92, 0xb8, 0xd6,
	0x7d, 0x3f, 0x1a, 0x66, 0x99, 0x86, 0x87, 0x07, 0xa5, 0x4b, 0x4c, 0x3a, 0x2b, 0xb3, 0x0a, 0xea,
	0xb3, 0xf6, 0xbc, 0x99, 0xdb, 0x9b, 0xfb, 0x9d, 0x66, 0x7e, 0xd4, 0x83, 0x51, 0x49, 0x67, 0x37,
	0x0f, 0x78, 0x1c, 0x67, 0x31, 0x5d, 0x61, 0xbe, 0x37, 0x23, 0x3b, 0x2b, 0xa1, 0x4a, 0xeb, 0x93,
	0xf6, 0xf4, 0xff, 0x43, 0xcc, 0x55, 0x0c, 0xe9, 0x02, 0x73, 0xee, 0x5e, 0x9d, 0xdb, 0x85, 0x15,
	0x0a, 0x15, 0xed, 0xfa, 0x06, 0x8b, 0xa5, 0x9b, 0x10, 0xf3, 0x6e, 0x96, 0x5b, 0xb1, 0x5a, 0xb8,
	0x15, 0xb0, 0xf0, 0x56, 0x24, 0x77, 0xe2, 0x6b, 0x2a, 0xe1, 0x7b, 0x2a, 0xe1, 0x67, 0x2a, 0xe1,
	0xf3, 0xb7, 0x5c, 0x3d, 0xe7, 0xe1, 0x0c, 0xdb, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x80, 0xbf,
	0xc4, 0x8f, 0x14, 0x01, 0x00, 0x00,
}

func (m *Student) Marshal() (dAtA []byte, err error) {
	size := m.Size()
	dAtA = make([]byte, size)
	n, err := m.MarshalToSizedBuffer(dAtA[:size])
	if err != nil {
		return nil, err
	}
	return dAtA[:n], nil
}

func (m *Student) MarshalTo(dAtA []byte) (int, error) {
	size := m.Size()
	return m.MarshalToSizedBuffer(dAtA[:size])
}

func (m *Student) MarshalToSizedBuffer(dAtA []byte) (int, error) {
	i := len(dAtA)
	_ = i
	var l int
	_ = l
	if m.XXX_unrecognized != nil {
		i -= len(m.XXX_unrecognized)
		copy(dAtA[i:], m.XXX_unrecognized)
	}
	if m.Cn != 0 {
		i = encodeVarintTest(dAtA, i, uint64(m.Cn))
		i--
		dAtA[i] = 0x20
	}
	if len(m.Address) > 0 {
		i -= len(m.Address)
		copy(dAtA[i:], m.Address)
		i = encodeVarintTest(dAtA, i, uint64(len(m.Address)))
		i--
		dAtA[i] = 0x1a
	}
	if m.Age != 0 {
		i = encodeVarintTest(dAtA, i, uint64(m.Age))
		i--
		dAtA[i] = 0x10
	}
	if len(m.Name) > 0 {
		i -= len(m.Name)
		copy(dAtA[i:], m.Name)
		i = encodeVarintTest(dAtA, i, uint64(len(m.Name)))
		i--
		dAtA[i] = 0xa
	}
	return len(dAtA) - i, nil
}

func (m *Students) Marshal() (dAtA []byte, err error) {
	size := m.Size()
	dAtA = make([]byte, size)
	n, err := m.MarshalToSizedBuffer(dAtA[:size])
	if err != nil {
		return nil, err
	}
	return dAtA[:n], nil
}

func (m *Students) MarshalTo(dAtA []byte) (int, error) {
	size := m.Size()
	return m.MarshalToSizedBuffer(dAtA[:size])
}

func (m *Students) MarshalToSizedBuffer(dAtA []byte) (int, error) {
	i := len(dAtA)
	_ = i
	var l int
	_ = l
	if m.XXX_unrecognized != nil {
		i -= len(m.XXX_unrecognized)
		copy(dAtA[i:], m.XXX_unrecognized)
	}
	if len(m.School) > 0 {
		i -= len(m.School)
		copy(dAtA[i:], m.School)
		i = encodeVarintTest(dAtA, i, uint64(len(m.School)))
		i--
		dAtA[i] = 0x12
	}
	if len(m.Person) > 0 {
		for iNdEx := len(m.Person) - 1; iNdEx >= 0; iNdEx-- {
			{
				size, err := m.Person[iNdEx].MarshalToSizedBuffer(dAtA[:i])
				if err != nil {
					return 0, err
				}
				i -= size
				i = encodeVarintTest(dAtA, i, uint64(size))
			}
			i--
			dAtA[i] = 0xa
		}
	}
	return len(dAtA) - i, nil
}

func encodeVarintTest(dAtA []byte, offset int, v uint64) int {
	offset -= sovTest(v)
	base := offset
	for v >= 1<<7 {
		dAtA[offset] = uint8(v&0x7f | 0x80)
		v >>= 7
		offset++
	}
	dAtA[offset] = uint8(v)
	return base
}
func (m *Student) Size() (n int) {
	if m == nil {
		return 0
	}
	var l int
	_ = l
	l = len(m.Name)
	if l > 0 {
		n += 1 + l + sovTest(uint64(l))
	}
	if m.Age != 0 {
		n += 1 + sovTest(uint64(m.Age))
	}
	l = len(m.Address)
	if l > 0 {
		n += 1 + l + sovTest(uint64(l))
	}
	if m.Cn != 0 {
		n += 1 + sovTest(uint64(m.Cn))
	}
	if m.XXX_unrecognized != nil {
		n += len(m.XXX_unrecognized)
	}
	return n
}

func (m *Students) Size() (n int) {
	if m == nil {
		return 0
	}
	var l int
	_ = l
	if len(m.Person) > 0 {
		for _, e := range m.Person {
			l = e.Size()
			n += 1 + l + sovTest(uint64(l))
		}
	}
	l = len(m.School)
	if l > 0 {
		n += 1 + l + sovTest(uint64(l))
	}
	if m.XXX_unrecognized != nil {
		n += len(m.XXX_unrecognized)
	}
	return n
}

func sovTest(x uint64) (n int) {
	return (math_bits.Len64(x|1) + 6) / 7
}
func sozTest(x uint64) (n int) {
	return sovTest(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *Student) Unmarshal(dAtA []byte) error {
	l := len(dAtA)
	iNdEx := 0
	for iNdEx < l {
		preIndex := iNdEx
		var wire uint64
		for shift := uint(0); ; shift += 7 {
			if shift >= 64 {
				return ErrIntOverflowTest
			}
			if iNdEx >= l {
				return io.ErrUnexpectedEOF
			}
			b := dAtA[iNdEx]
			iNdEx++
			wire |= uint64(b&0x7F) << shift
			if b < 0x80 {
				break
			}
		}
		fieldNum := int32(wire >> 3)
		wireType := int(wire & 0x7)
		if wireType == 4 {
			return fmt.Errorf("proto: Student: wiretype end group for non-group")
		}
		if fieldNum <= 0 {
			return fmt.Errorf("proto: Student: illegal tag %d (wire type %d)", fieldNum, wire)
		}
		switch fieldNum {
		case 1:
			if wireType != 2 {
				return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType)
			}
			var stringLen uint64
			for shift := uint(0); ; shift += 7 {
				if shift >= 64 {
					return ErrIntOverflowTest
				}
				if iNdEx >= l {
					return io.ErrUnexpectedEOF
				}
				b := dAtA[iNdEx]
				iNdEx++
				stringLen |= uint64(b&0x7F) << shift
				if b < 0x80 {
					break
				}
			}
			intStringLen := int(stringLen)
			if intStringLen < 0 {
				return ErrInvalidLengthTest
			}
			postIndex := iNdEx + intStringLen
			if postIndex < 0 {
				return ErrInvalidLengthTest
			}
			if postIndex > l {
				return io.ErrUnexpectedEOF
			}
			m.Name = string(dAtA[iNdEx:postIndex])
			iNdEx = postIndex
		case 2:
			if wireType != 0 {
				return fmt.Errorf("proto: wrong wireType = %d for field Age", wireType)
			}
			m.Age = 0
			for shift := uint(0); ; shift += 7 {
				if shift >= 64 {
					return ErrIntOverflowTest
				}
				if iNdEx >= l {
					return io.ErrUnexpectedEOF
				}
				b := dAtA[iNdEx]
				iNdEx++
				m.Age |= int32(b&0x7F) << shift
				if b < 0x80 {
					break
				}
			}
		case 3:
			if wireType != 2 {
				return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType)
			}
			var stringLen uint64
			for shift := uint(0); ; shift += 7 {
				if shift >= 64 {
					return ErrIntOverflowTest
				}
				if iNdEx >= l {
					return io.ErrUnexpectedEOF
				}
				b := dAtA[iNdEx]
				iNdEx++
				stringLen |= uint64(b&0x7F) << shift
				if b < 0x80 {
					break
				}
			}
			intStringLen := int(stringLen)
			if intStringLen < 0 {
				return ErrInvalidLengthTest
			}
			postIndex := iNdEx + intStringLen
			if postIndex < 0 {
				return ErrInvalidLengthTest
			}
			if postIndex > l {
				return io.ErrUnexpectedEOF
			}
			m.Address = string(dAtA[iNdEx:postIndex])
			iNdEx = postIndex
		case 4:
			if wireType != 0 {
				return fmt.Errorf("proto: wrong wireType = %d for field Cn", wireType)
			}
			m.Cn = 0
			for shift := uint(0); ; shift += 7 {
				if shift >= 64 {
					return ErrIntOverflowTest
				}
				if iNdEx >= l {
					return io.ErrUnexpectedEOF
				}
				b := dAtA[iNdEx]
				iNdEx++
				m.Cn |= ClassName(b&0x7F) << shift
				if b < 0x80 {
					break
				}
			}
		default:
			iNdEx = preIndex
			skippy, err := skipTest(dAtA[iNdEx:])
			if err != nil {
				return err
			}
			if (skippy < 0) || (iNdEx+skippy) < 0 {
				return ErrInvalidLengthTest
			}
			if (iNdEx + skippy) > l {
				return io.ErrUnexpectedEOF
			}
			m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
			iNdEx += skippy
		}
	}

	if iNdEx > l {
		return io.ErrUnexpectedEOF
	}
	return nil
}
func (m *Students) Unmarshal(dAtA []byte) error {
	l := len(dAtA)
	iNdEx := 0
	for iNdEx < l {
		preIndex := iNdEx
		var wire uint64
		for shift := uint(0); ; shift += 7 {
			if shift >= 64 {
				return ErrIntOverflowTest
			}
			if iNdEx >= l {
				return io.ErrUnexpectedEOF
			}
			b := dAtA[iNdEx]
			iNdEx++
			wire |= uint64(b&0x7F) << shift
			if b < 0x80 {
				break
			}
		}
		fieldNum := int32(wire >> 3)
		wireType := int(wire & 0x7)
		if wireType == 4 {
			return fmt.Errorf("proto: Students: wiretype end group for non-group")
		}
		if fieldNum <= 0 {
			return fmt.Errorf("proto: Students: illegal tag %d (wire type %d)", fieldNum, wire)
		}
		switch fieldNum {
		case 1:
			if wireType != 2 {
				return fmt.Errorf("proto: wrong wireType = %d for field Person", wireType)
			}
			var msglen int
			for shift := uint(0); ; shift += 7 {
				if shift >= 64 {
					return ErrIntOverflowTest
				}
				if iNdEx >= l {
					return io.ErrUnexpectedEOF
				}
				b := dAtA[iNdEx]
				iNdEx++
				msglen |= int(b&0x7F) << shift
				if b < 0x80 {
					break
				}
			}
			if msglen < 0 {
				return ErrInvalidLengthTest
			}
			postIndex := iNdEx + msglen
			if postIndex < 0 {
				return ErrInvalidLengthTest
			}
			if postIndex > l {
				return io.ErrUnexpectedEOF
			}
			m.Person = append(m.Person, &Student{})
			if err := m.Person[len(m.Person)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
				return err
			}
			iNdEx = postIndex
		case 2:
			if wireType != 2 {
				return fmt.Errorf("proto: wrong wireType = %d for field School", wireType)
			}
			var stringLen uint64
			for shift := uint(0); ; shift += 7 {
				if shift >= 64 {
					return ErrIntOverflowTest
				}
				if iNdEx >= l {
					return io.ErrUnexpectedEOF
				}
				b := dAtA[iNdEx]
				iNdEx++
				stringLen |= uint64(b&0x7F) << shift
				if b < 0x80 {
					break
				}
			}
			intStringLen := int(stringLen)
			if intStringLen < 0 {
				return ErrInvalidLengthTest
			}
			postIndex := iNdEx + intStringLen
			if postIndex < 0 {
				return ErrInvalidLengthTest
			}
			if postIndex > l {
				return io.ErrUnexpectedEOF
			}
			m.School = string(dAtA[iNdEx:postIndex])
			iNdEx = postIndex
		default:
			iNdEx = preIndex
			skippy, err := skipTest(dAtA[iNdEx:])
			if err != nil {
				return err
			}
			if (skippy < 0) || (iNdEx+skippy) < 0 {
				return ErrInvalidLengthTest
			}
			if (iNdEx + skippy) > l {
				return io.ErrUnexpectedEOF
			}
			m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
			iNdEx += skippy
		}
	}

	if iNdEx > l {
		return io.ErrUnexpectedEOF
	}
	return nil
}
func skipTest(dAtA []byte) (n int, err error) {
	l := len(dAtA)
	iNdEx := 0
	depth := 0
	for iNdEx < l {
		var wire uint64
		for shift := uint(0); ; shift += 7 {
			if shift >= 64 {
				return 0, ErrIntOverflowTest
			}
			if iNdEx >= l {
				return 0, io.ErrUnexpectedEOF
			}
			b := dAtA[iNdEx]
			iNdEx++
			wire |= (uint64(b) & 0x7F) << shift
			if b < 0x80 {
				break
			}
		}
		wireType := int(wire & 0x7)
		switch wireType {
		case 0:
			for shift := uint(0); ; shift += 7 {
				if shift >= 64 {
					return 0, ErrIntOverflowTest
				}
				if iNdEx >= l {
					return 0, io.ErrUnexpectedEOF
				}
				iNdEx++
				if dAtA[iNdEx-1] < 0x80 {
					break
				}
			}
		case 1:
			iNdEx += 8
		case 2:
			var length int
			for shift := uint(0); ; shift += 7 {
				if shift >= 64 {
					return 0, ErrIntOverflowTest
				}
				if iNdEx >= l {
					return 0, io.ErrUnexpectedEOF
				}
				b := dAtA[iNdEx]
				iNdEx++
				length |= (int(b) & 0x7F) << shift
				if b < 0x80 {
					break
				}
			}
			if length < 0 {
				return 0, ErrInvalidLengthTest
			}
			iNdEx += length
		case 3:
			depth++
		case 4:
			if depth == 0 {
				return 0, ErrUnexpectedEndOfGroupTest
			}
			depth--
		case 5:
			iNdEx += 4
		default:
			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
		}
		if iNdEx < 0 {
			return 0, ErrInvalidLengthTest
		}
		if depth == 0 {
			return iNdEx, nil
		}
	}
	return 0, io.ErrUnexpectedEOF
}

var (
	ErrInvalidLengthTest        = fmt.Errorf("proto: negative length found during unmarshaling")
	ErrIntOverflowTest          = fmt.Errorf("proto: integer overflow")
	ErrUnexpectedEndOfGroupTest = fmt.Errorf("proto: unexpected end of group")
)

  可以看成,将protobuf message对应的内容生成结构体,通过GetXX方法来获取对应的值。

Golang的使用

package main

import (
	"fmt"

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

func main() {
	s1 := &Student{} //第一个学生信息
	s1.Name = "jz01"
	s1.Age = 23
	s1.Address = "cq"
	s1.Cn = ClassName_class2 //枚举类型赋值
	ss := &Students{}
	ss.Person = append(ss.Person, s1) //将第一个学生信息添加到Students对应的切片中
	s2 := &Student{}                  //第二个学生信息
	s2.Name = "jz02"
	s2.Age = 25
	s2.Address = "cd"
	s2.Cn = ClassName_class3
	ss.Person = append(ss.Person, s2) //将第二个学生信息添加到Students对应的切片中
	ss.School = "cqu"
	fmt.Println("Students信息为:", ss)

	// Marshal takes a protocol buffer message
	// and encodes it into the wire format, returning the data.
	buffer, _ := proto.Marshal(ss)
	fmt.Println("序列化之后的信息为:", buffer)
	//  Use UnmarshalMerge to preserve and append to existing data.
	data := &Students{}
	proto.Unmarshal(buffer, data)
	fmt.Println("反序列化之后的信息为:", data)
	for i := 0; i < len(ss.Person); i++ {
		s11 := ss.Person[i]
		fmt.Println(s11)
	}
}

  注:序列化以后数据被转换成二进制类型(即适合于网络传输的protobuf类型,也就是将结构体类型转换为protobuf类型),反序列化后直接写入(转换)对应的结构体类型(也就是将protobuf类型转换为对应的结构体类型)。

测试结果

D:/go/src/pb/pb.exe [D:/go/src/pb]

Students信息为: person:<name:"jz01" age:23 address:"cq" cn:class2 > person:<name:"jz02" age:25 address:"cd" cn:class3 > school:"cqu"

序列化之后的信息为: [10 14 10 4 106 122 48 49 16 23 26 2 99 113 32 1 10 14 10 4 106 122 48 50 16 25 26 2 99 100 32 2 18 3 99 113 117]

反序列化之后的信息为: person:<name:"jz01" age:23 address:"cq" cn:class2 > person:<name:"jz02" age:25 address:"cd" cn:class3 > school:"cqu"

name:"jz01" age:23 address:"cq" cn:class2

name:"jz02" age:25 address:"cd" cn:class3

成功: 进程退出代码 0.

  

 

原文地址:https://www.cnblogs.com/hnxxcxg/p/15253788.html