在go 中 protobuf 是如何import 其他protobuf文件,且支持go modules

1. protobuf 的安装和使用

1.1安装

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

1.2 安装go protobuf相关编译文件

目前来说 有两种 一个是官方出品 还有一个是gogo团队的
我们用官方的
以下是一些命令
安装相关编译功能的文件

go get github.com/golang/protobuf/proto

安装插件

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

生成go文件

protoc --go_out=. *.proto

具体语法可以查看官方文档https://developers.google.com/protocol-buffers/

2.多proto文件import

2.1 新建两个proto文件

分别为test1.proto test2.proto 文件, 我们要在test2.proto中引用test1.proto 并且go 1.3版本中支持 go modules

test1.proto

syntax = "proto3";
package test1;//包名
option  go_package = "niuniu/test1";//设置go包的可选项


message   newdata {
     int32  id=1;
     string info=2;
}

test2.proto

syntax = "proto3";
option go_package="niuniu/test2";//可选项设置包的地址
import "test1.proto";

message   datamsg {
   test1.newdata newinfo=1;//这里调用test1.newdata
}

我的建议是proto文件名和 package 文件名 和go_package 的包的后面的名字都保持一致
这里重要的是option go_package 一定要设置

2.2 生成go文件

我们先生成 test1.pb.go文件
跑一下命令

 protoc  --go_out=./ test1.proto

然后我们就看到 在目录下面生成了


我们生成test2.pb.go文件
跑一下命令

 protoc  --go_out=./ test2.proto

我们可以看到test2.pb.go 文件已经生成了


我们看一下 test2.pb.go import 引入了什么


我们看到了 fmt proto math 和test1

我们看下结构体里面有了 *test1.Newdata


这样引用就已经完成了

3 在go文件中 用pb.go 文件

package main

import (
    "fmt"
    "github.com/golang/protobuf/proto"
    "log"
    "niuniu/test1" //引入包test1
    "niuniu/test2"//引入包test2
)

func main() {
    fmt.Println("1111")
      //调用test1.Newdata方法
    test3 := &test1.Newdata{
        Id:   1,
        Info: "我是主消息",
    }
    //fmt.Println(testmsg);
       //序列化test3 调用 proto.Marshal
    data, err := proto.Marshal(test3)
    fmt.Println(data)
    if err != nil {
        log.Fatal("marshaling error: ", err)
    }
    //fmt.Println(data)
    newTest := &test1.Newdata{}
       //反序列化
    err =proto.Unmarshal(data,newTest)
    if err != nil {
        log.Fatal("unmarshaling error: ", err)
    }
    fmt.Println(newTest)

    fmt.Println(newTest.Id)
    fmt.Println(newTest.Info)

      //调用test2
    test2msg := &test2.Datamsg{
        Newinfo: test3,
    }

    if err != nil {
        log.Fatal("marshaling error: ", err)
    }
    //fmt.Println(data)

    fmt.Println(test2msg.Newinfo.Info)

}

然后 go run main.go 我们发现编辑器goland会不知道这个两个包在哪里
我们把生成的niuniu文件 复制到 GOPATH/src 目录下 这下编译器认识了

cannot load niuniu/test1: malformed module path "niuniu/test1": missing dot in first path element\

我们去go.mod 文件里面写点东西 来指定这个包

replace  "niuniu/test1"=>./niuniu/test1  //后面为指定地址

replace "niuniu/test2"=>./niuniu/test2   //指定地址

然后发现还是报错

go: niuniu/test1: parsing niuniu\test1\go.mod: open D:\Gostudy\rui\niuniu\test1\go.mod: The system cannot find the file specified.

说解析不到go.mod
那我们就去test1和test2中分别建一个go.mod文件

这样我们就可以愉快的跑起来辣
这里的重点是go_package 这个我们在引入的时候 我们没写 他就默认的引入当前的,而编译器不认识 这些package去GOPATH里面找也找不到 就会 没有报这个包的错误

你可能感兴趣的:(在go 中 protobuf 是如何import 其他protobuf文件,且支持go modules)