set_
get_
方法string
類型的字段可使用 mutable_
方法來直接得到字符串的指針。optional
修飾的類型, 在沒有對string類型賦值時也可使用這個方法 mutable_
方法,由於會幫咱們自動初始化爲 empty string
。Repeated fields
有特殊的方法:
_size
add_
方法,能夠添加新的值以便後面修改bool IsInitialized() const;
(判斷當前字段是否被初始化)string DebugString() const;
(轉換爲字符串的形式,方便調試查看)void CopyFrom(const Person& from);
(重寫給定的消息結構)void Clear();
(清除全部元素,返回空)Parsing and Serialization
)bool SerializeToString(string* output) const;
bool ParseFromString(const string& data);
bool SerializeToOstream(ostream* output) const;
bool ParseFromIstream(istream* input);
google提到:正則表達式
Protocol Buffers and O-O Design Protocol buffer classes are basically dumb data holders (like structs in C); they don't make good first class citizens in an object model. If you want to add richer behaviour to a generated class, the best way to do this is to wrap the generated protocol buffer class in an application-specific class. Wrapping protocol buffers is also a good idea if you don't have control over the design of the .proto file (if, say, you're reusing one from another project). In that case, you can use the wrapper class to craft an interface better suited to the unique environment of your application: hiding some data and methods, exposing convenience functions, etc. You should never add behaviour to the generated classes by inheriting from them. This will break internal mechanisms and is not good object-oriented practice anyway.api
特別提到 Protobuf
是根據面向對象設計的設計理念來設計的。因此咱們能夠把面向對象設計的設計思路應用其中。數據結構
protobuf Message
功能是比較單一的,能夠把protobuf
的結構化數據經過應用程序來進一步封裝,達到功能更豐富的地步。爲了使Protobuf
擁有向前兼容,向後拓展的能力,須要按照以下作:app
Protobuf
在存儲時的key
啊。required
修飾的字段optional
或repeated
字段optional
或repeated
修飾的字段,可是標籤須要是惟一不衝突的。從這裏能夠看到,Protobuf
在底層的存儲方式是 Tag-Length-Value
,標識-長度-字段值。其中的Length
是可選的。ide
爲了兼容和健壯,字段被刪除或者更新時,對於應用程序來講是透明的(對於舊代碼,已刪除的可選字段將只有默認值,已刪除的重複字段將爲空。新代碼還將透明地讀取舊消息),最好是在定義字段最後加上默認值,而且是在使用時先經過 has_
方法 來判斷該字段是否存在。優化
string(NULL)
booleans(false)
number(0)
Protobuf
已經被極度優化過了,因此纔有現在的這麼高效,可是還能夠提供下面幾個建議達到更優:ui
儘量複用消息對象。即便在清除內存時,消息依然保留分配給它們的任何內存,以便未來複用。所以,若是正在連續處理許多具備相同類型和相似結構的消息,那麼最好每次複用相同的消息對象,以減輕內存分配器的負載。然而,隨着時間的推移,對象可能會變得膨脹,特別是當您的消息在「形狀」上發生變化時,或者若是您偶爾構造一個比一般大得多的消息時。您應該經過調用
SpaceUsed
方法來監視消息對象的大小,並在達到某個大小時強制刪除對象釋放內存。this
系統默認的內存分配器經過多個線程分配大量小對象時優化可能不太好,能夠嘗試使用
tcmalloc
代替。google
Protobuf
的一個關鍵特性是反射。咱們能夠遍歷消息的字段並操做它們的值,而無需針對任何特定的消息類型編寫代碼。編碼
使用反射的一種很是有用的方法是將Protobuf
消息格式轉換爲其餘編碼(如XML
或JSON
)。
反射更高級的用途多是查找同一類型的兩個消息之間的差別,或者開發一種「協議消息正則表達式」,能夠在其中編寫匹配特定消息內容的表達式。這樣就能夠實現動態的修改消息結構,達到運行時修改協議類型。