默認(rèn)值
解析消息時(shí), 如果被編碼的消息沒(méi)有包含一個(gè)特定的元素, 被解析的對(duì)象對(duì)應(yīng)的字段被設(shè)置為默認(rèn)值. 默認(rèn)值是和類型有關(guān)的:
- 對(duì)于strings, 默認(rèn)值是空字符串(注, 是"", 而不是null)
- 對(duì)于bytes, 默認(rèn)值是空字節(jié)(注, 應(yīng)該是byte[0], 注意這里也不是null)
- 對(duì)于bool, 默認(rèn)值是false.
- 對(duì)于數(shù)字類型, 默認(rèn)值是0.
- 對(duì)于枚舉, 默認(rèn)值是第一個(gè)定義的枚舉值, 而這個(gè)值必須是0.
- 對(duì)于消息字段, 默認(rèn)值和語(yǔ)言相關(guān)查牌,參考generated code guide
- 對(duì)于重復(fù)字段, 默認(rèn)值是空(通常都是空列表)
注意: 對(duì)于基本的消息字段, 當(dāng)消息被解析后, 是不知道該值是默認(rèn)值還是剛好設(shè)置了和默認(rèn)值相同的值(例如一個(gè)bool設(shè)置為false师痕,當(dāng)你不希望這個(gè)bool變量能控制程序的默認(rèn)行為躲舌,不要用一個(gè)bool值然后當(dāng)設(shè)置為false時(shí)來(lái)切換某些行為。同樣請(qǐng)注意: 如果一個(gè)簡(jiǎn)單消息字段被設(shè)置為它的默認(rèn)值, 這個(gè)值不會(huì)被序列化.
枚舉
簡(jiǎn)單示例
在下面的例子中, 服務(wù)消息中添加一個(gè)名為Corpus的枚舉類型, 定義好所有可能的值, 然后添加一個(gè)類型為Corpus的字段:
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
enum Corpus {
UNIVERSAL = 0;
WEB = 1;
IMAGES = 2;
LOCAL = 3;
NEWS = 4;
PRODUCTS = 5;
VIDEO = 6;
}
Corpus corpus = 4;
}
如上, Corpus 枚舉的第一個(gè)常量設(shè)置到0: 每個(gè)枚舉定義必須包含一個(gè)映射到0的常量作為它的第一個(gè)元素. 這是因?yàn)?
- 默認(rèn)值:必須有一個(gè)0值, 這樣我們才能用0來(lái)作為數(shù)值默認(rèn)值.
- 兼容性:0值必須是第一個(gè)元素, 兼容proto2語(yǔ)法,在proto2中默認(rèn)值總是第一個(gè)枚舉值
別名設(shè)置
可以通過(guò)將相同值賦值給不同的枚舉常量來(lái)定義別名口予。需要設(shè)置allow_alias選項(xiàng)為true, 否則當(dāng)發(fā)現(xiàn)別名時(shí)protocol編譯器會(huì)報(bào)錯(cuò)娄周。
enum EnumAllowingAlias {
option allow_alias = true;
UNKNOWN = 0;
STARTED = 1;
RUNNING = 1;
}
enum EnumNotAllowingAlias {
UNKNOWN = 0;
STARTED = 1;
// RUNNING = 1; // Uncommenting this line will cause a compile error inside Google and a warning message outside.
}
注意事項(xiàng)
枚舉常量必須在32位整形的范圍內(nèi),由于枚舉值使用varint encoding沪停,如果設(shè)置為負(fù)值煤辨,效率比較低不推薦使用裳涛。你可以在消息定義中定義枚舉, 如前面例子, 或者在外部 - 這些枚舉可以在.proto文件的任意消息定義中復(fù)用。在一個(gè)消息中聲明的枚舉類型作為別的消息的字段類型, 需要使用語(yǔ)法MessageType.EnumType.
保留字段
當(dāng)你在某次更新消息中屏蔽或者刪除了一個(gè)字段的話众辨,未來(lái)的使用著可能在他們的更新中重用這個(gè)標(biāo)簽數(shù)字來(lái)標(biāo)記他們自己的字段端三。然后當(dāng)他們加載舊的消息的時(shí)候就會(huì)出現(xiàn)很多問(wèn)題,包括數(shù)據(jù)沖突鹃彻,隱藏的bug等等郊闯。指定這個(gè)字段的標(biāo)簽數(shù)字(或者名字,名字可能在序列化為JSON的時(shí)候可能沖突)標(biāo)記為reserved來(lái)保證他們不會(huì)再次被使用蛛株。如果以后的人試用的話protobuf編譯器會(huì)提示出錯(cuò)团赁。
enum Foo {
reserved 2, 15, 9 to 11, 40 to max;
reserved "FOO", "BAR";
}
注意一個(gè)reserved字段不能既有標(biāo)簽數(shù)字又有名字。
注意:生成的枚舉類型數(shù)量代碼可能會(huì)受到語(yǔ)言限制(一般低于1000泳挥,具體參考語(yǔ)言類型限制)