关于import语句,google说https://developers.google.com/protocol-buffers/docs/proto#services:
您可以通过导入来使用其他.proto文件中的定义。要导入另一个.proto的定义,可以在文件顶部添加import语句。 默认情况下,您只能使用直接导入的.proto文件中的定义。
......听起来不错,但那是怎么回事:
1.proto:
message M1{
required string foo = 1;
}
2.proto:
import "1.proto";
message M2{
required M1 m_1 = 1;
}
3.proto:
import "2.proto";
message M3{
required M2 m_2 = 1;
}
因此,在解析3.proto时,M1不应该是可访问的,因为1.proto不是从2.proto公开导入的。 但是,M2应该是,因为它直接从3.proto ...
导入那么M2.m_1怎么样?编译器应该如何生成类?
答案 0 :(得分:2)
文档的含义是,如果您想在文件中引用M1
,则必须导入1.proto
,如果要在文件中引用M2
,必须导入2.proto
。您 not 需要显式导入隐式/传递依赖项。在不导入M2
的情况下使用1.proto
非常好。
编译器实际上遵循传递导入并读取所有三个文件,以便为3.proto
生成代码。此外,在C ++中,3.pb2.h
将#include "2.pb2.h"
,而#include "1.pb2.h"
依次为M1
。该规则只是一种语法规则。
为什么要这个规则?好吧,考虑一下您是否可以在3.proto
中直接使用1.proto
而不显式导入2.proto
,只是因为您导入了自己导入1.proto
的{{1}}。现在考虑,2.proto
的维护者是否决定删除字段m_1
。现在2.proto
没有使用M1
,因此维护者决定删除1.proto
的导入。但现在3.proto
已被破坏,因为它依赖2.proto
导入1.proto
的事实!
这是C ++包含的常见问题。我不想在Protobufs中遇到同样的问题,所以我制定了一条规则,你必须明确导入所有文件,声明你在自己的文件中明确使用的类型。