版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、ProtoBuf開發(fā)者指南 i概覽o1.1什么是protocolbuffero1.2他們如何工作o1.3為什么不用XML?o1.4聽起來像是為我的解決方案,如何開始o1.5一點歷史 2語言指導o2.1定義一個消息類型o2.2值類型o2.3可選字段與缺省值o2.4枚舉o2.5使用其他消息類型o2.6嵌套類型o2.7更新一個數(shù)據(jù)類型o2.8擴展o2.9包o2.10定義服務o2.11選項o2.12生成你的類 3代碼風格指導o3.1消息與字段名o3.2枚舉o3.3服務 4編碼o4.1一個簡單的消息o4.2基于128的Varintso4.3消息結構o4.4更多的值類型o4.5內嵌消息o4.6可選的和重復
2、的元素o4.7字段順序 5ProtocolBuffer基礎:C+ 6ProtocolBuffer基礎:Java 7ProtocolBuffer基礎:Pythono7.1為什么使用ProtocolBuffer?o7.2哪里可以找到例子代碼o7.3定義你的協(xié)議格式o7.4編譯你的ProtocolBuffero7.5ProtocolBufferAPI7.5.1 枚舉7.5.2 標準消息方法7.5.3 解析與串行化07.6寫消息07.7讀消息07.8擴展ProtocolBuffer07.9高級使用1.1.1 8參考概覽2.2.2 9C+代碼生成3.3.3 10C+API4.4.4 11Java代碼生成
3、112JavaAPI5.5.5 13Python代碼生成o13.1編譯器的使用o13.2包o13.3消息o13.4字段 簡單字段 簡單消息字段 重復字段 重復消息字段 枚舉類型 擴展o13.5服務 接口 存根(Stub)14PythonAPI15其他語言1概覽歡迎來到protocolbuffer的開發(fā)者指南文檔,一種語言無關、平臺無關、擴展性好的用于通信協(xié)議、數(shù)據(jù)存儲的結構化數(shù)據(jù)串行化方法。本文檔面向希望使用protocolbuffer的Java、C+或Python開發(fā)者。這個概覽介紹了protocolbuffer,并告訴你如何開始,你隨后可以跟隨編程指導(語言的版本,不夠協(xié)議語言( 什么是p
4、rotocolbufferProtocolBuffer是用于結構化數(shù)據(jù)串行化的靈活、高效、自動的方法,有如XML,不過它更小、更快、也更簡單。你可以定義自己的數(shù)據(jù)結構,然后使用代碼生成器生成的代碼來讀寫這個數(shù)據(jù)結構。你甚至可以在無需重新部署程序的情況下更新數(shù)據(jù)結構。 他們如何工作你首先需要在一個.proto文件中定義你需要做串行化的數(shù)據(jù)結構信息。每個ProtocolBuffer信息是一小段邏輯記錄,包含一系列的鍵值對。這里有個非常簡單的.proto文件定義了個人信息:messagePersonrequiredstringname=1;requiredint32id=2;optionalstri
5、ngemail=3;enumPhoneTypeMOBILE=0;HOME=1;WORK=2;messagePhoneNumberrequiredstringnumber=1;optionalPhoneTypetype=2default=HOME;repeatedPhoneNumberphone=4;有如你所見,消息格式很簡單,每個消息類型擁有一個或多個特定的數(shù)字字段,每個字段擁有一個名字和一個值類型。值類型可以是數(shù)字(整數(shù)或浮點卜布爾型、字符串、原始字節(jié)或者其他ProtocolBuffer類型,還允許數(shù)據(jù)結構的分級。你可以指定可選字段,必選字段和重復字段。你可以在(一旦你定義了自己的報文格式(
6、message),你就可以運行ProtocolBuffer編譯器,將你的.proto文件編譯成特定語言的類。這些類提供了簡單的方法訪問每個字段(像是query()和set_query(),像是訪問類的方法一樣將結構串行化或反串行化。例如你可以選擇C+語言,運行編譯如上的協(xié)議文件生成類叫做Person。隨后你就可以在應用中使用這個類來串行化的讀取報文信息。你可以這么寫代碼:Personperson;person.set_name("JohnDoe");person.set_id(1234);person.set_email("jdoe");fstream.
7、output("myfile",ios二out|ios二binary);person.SerializeToOstream(&output);然后,你可以讀取報文中的數(shù)據(jù):fstreaminput("myfile",ios:in|ios:binary);Personperson;person.ParseFromIstream(&input);cout<<"Name:"<<()<<endl;cout<<"E-mail:"<&l
8、t;person.email()<<endl;你可以在不影響向后兼容的情況下隨意給數(shù)據(jù)結構增加字段,舊有的數(shù)據(jù)會忽略新的字段。所以如果使用ProtocolBuffer作為通信協(xié)議,你可以無須擔心破壞現(xiàn)有代碼的情況下擴展協(xié)議。你可以在API參考(整的參考,而關于ProtocolBuffer的報文格式編碼則可以在( 為什么不用XML?ProtocolBuffer擁有多項比XML更高級的串行化結構數(shù)據(jù)的特性,ProtocolBuffer1.1.1 更簡單2.2.2 小3-10倍3.3.3 快20-100倍4.4.4 更少的歧義5.5.5 可以方便的生成數(shù)據(jù)存取類例如,讓我們看看如何在XM
9、L中建模Person的name和email字段:<person><name>JohnDoe</name><email>jdoe</email></person>對應的ProtocolBuffer報文則如下:#ProtocolBuffer的文本表示#這不是正常時使用的二進制數(shù)據(jù)personname:"JohnDoe"email:"jdoe)當這個報文編碼到ProtocolBuffer的二進制格式(只需要28字節(jié)和100-200ns的解析時間。而XML的版本需要69字節(jié)(除去空白)和5000-10
10、000ns的解析時間。當然,操作ProtocolBuffer也很簡單:cout<<"Name:"<<()<<endl;cout<<"E-mail:"<<person.email()<<endl;而XML的你需要:cout<<"Name:"<<person.getElementsByTagName("name")->item(0)->innerText()<<endl;cout
11、<<"E-mail:"<<person.getElementsByTagName("email")->item(0)->innerText()<<end;當然,ProtocolBuffer并不是在任何時候都比XML更合適,例如ProtocolBuffer無法對一個基于標記文本的文檔建模,因為你根本沒法方便的在文本中插入結構。另外,XML是便于人類閱讀和編輯的,而ProtocolBuffer則不是。還有XML是自解釋的,而ProtocolBuffer僅在你擁有報文格式定義的.proto文件時才有意義。聽起來像
12、是為我的解決方案,如何開始?下載包(http:編譯器,用于生成你需要的IO類。構建和安裝你的編譯器,跟隨README的指令就可以做到。一旦你安裝好了,就可以跟著編程指導(來選擇語言-隨后就是使用ProtocolBuffer創(chuàng)建一個簡單的應用了。一點歷史ProtocolBuffer最初是在Google開發(fā)的,用以解決索引服務器的請求、響應協(xié)議。在使用ProtocolBuffer之前,有一種格式用以處理請求和響應數(shù)據(jù)的編碼和解碼,并且支持多種版本的協(xié)議。而這最終導致了丑陋的代碼,有如:if(version=3)elseif(version>4)if(version=5)通信協(xié)議因此變得越來越
13、復雜,因為開發(fā)者必須確保,發(fā)出請求的人和接受請求的人必須同時兼容,并且在一方開始使用新協(xié)議時,另外一方也要可以接受。ProtocolBuffer設計用于解決這一類問題:很方便引入新字段,而中間服務器可以忽略這些字段,直接傳遞過去而無需理解所有的字段。格式可以自描述,并且可以在多種語言中使用(C+、Java等)然而用戶仍然需要手寫解析代碼。隨著系統(tǒng)的演化,他需要一些其他的功能:自動生成編碼和解碼代碼,而無需自己編寫解析器。除了用于簡短的RPC(RemoteProcedureCall)請求,人們使用ProtocolBuffer來做數(shù)據(jù)存儲格式(例如BitTable)。RPC服務器接口可以作為.pr
14、oto文件來描述,而通過ProtocolBuffer的編譯器生成存根(stub)類供用戶實現(xiàn)服務器接口。ProtocolBuffer現(xiàn)在已經(jīng)是Google的混合語言數(shù)據(jù)標準了,現(xiàn)在已經(jīng)正在使用的有超過48,162種報文格式定義和超過12,183個.proto文件。他們用于RPC系統(tǒng)和持續(xù)數(shù)據(jù)存儲系統(tǒng)。2語言指導本指導描述了如何使用ProtocolBuffer語言來定義結構化數(shù)據(jù)類型,包括.proto文件的語法和如何生成存取類。這是一份指導手冊,一步步的例子使用文檔中的多種功能,查看入門指導(http:2定義一個消息類型waiting值類型waiting可選字段與缺省值waiting枚舉wait
15、ing使用其他消息類型waiting嵌套類型waiting更新一個數(shù)據(jù)類型waiting擴展waiting包waiting定義服務waiting選項waiting生成你的類waiting3代碼風格指導本文檔提供了.proto文件的代碼風格指導。按照慣例,你將會,你將會生成一些便于閱讀和一致的ProtocolBuffer定義文件。3.1消息與字段名使用駱駝風格的大小寫命名,即單詞首字母大寫,來做消息名。使用GNU的全部小寫,使用下劃線分隔的方式定義字段名:messageSongServerRequestrequiredstringsong_name=1;使用這種命名方式得到的名字如下:C+:co
16、nststring&song_name().voidset_song_name(conststring&x).Java:publicStringgetSongName().publicBuildersetSongName(Stringv).3.2攻舉使用駱駝風格做枚舉名,而用全部大寫做值的名字enumFooFIRST_VALUE=1;SECOND_VALUE=2;每個枚舉值最后以分號結尾,而不是逗號3.3服務如果你的.proto文件定義了RPC服務,你可以使用駱駝風格:serviceFooServicerpcGetSomething(FooRequest)returns(Foo
17、Response);)4編碼本文檔描述了ProtocolBuffer的串行化二進制數(shù)據(jù)格式定義。你如果僅僅是在應用中使用ProtocolBuffer,并不需要知道這些,但是這些會對你定義高效的格式有所幫助。4.1一個簡單的消息waiting4.2基于128的Varintswaiting4.3消息結構waiting更多的值類型waiting內嵌消息waiting可選的和重復的元素waiting字段順序waiting5ProtocolBuffer基礎:C+waitingProtocolBuffer基礎:JavawaitingProtocolBuffer基礎:Python本指南給Python程序員一
18、個快速使用的ProtocolBuffer的指導。通過一些簡單的例子來在應用中使用ProtocolBuffer,它向你展示了如何:定義.proto消息格式文件使用ProtocolBuffer編譯器使用Python的ProtocolBuffer編程接口來讀寫消息這并不是一個在Python中使用ProtocolBuffer的完整指導。更多細節(jié)請參考手冊信息,查看語言指導(API(為什么使用ProtocolBuffer?下面的例子"地址本"應用用于讀寫人的聯(lián)系信息。每個人有name、ID、email,和聯(lián)系人電話號碼。如何串行化和讀取結構化數(shù)據(jù)呢?有如下幾種問題:使用Python的
19、pickle,這是語言內置的缺省方法,不過沒法演化,也無法讓其他語言支持。你可以發(fā)明一種數(shù)據(jù)編碼方法,例如4個整數(shù)”12:323:67,這是簡單而靈活的方法,不過你需要自己寫解析器代碼,且只適用于簡單的數(shù)據(jù)。串行化數(shù)據(jù)到XML。這種方法因為可讀性和多種語言的兼容函數(shù)庫而顯得比較吸引人,不過這也不是最好的方法,因為XML浪費空間是臭名昭著的,編碼解碼也很浪費時間。而XMLDOM樹也是很復雜的。ProtocolBuffer提供了靈活、高效、自動化的方法來解決這些問題。通過ProtocolBuffer,只需要寫一個.proto數(shù)據(jù)結構描述文件,就可以編譯到幾種語言的自動編碼解碼類。生成的類提供了se
20、tter和getter方法來控制讀寫細節(jié)。最重要的是ProtocolBuffer支持后期擴展協(xié)議,而又確保舊格式可以兼容。哪里可以找到例子代碼源碼發(fā)行包中已經(jīng)包含了,在example'文件夾定義你的協(xié)議格式想要創(chuàng)建你的地址本應用,需要開始于一個.proto文件。定義一個.proto文件很簡單:添加一個消息到數(shù)據(jù)結構,然后指定一個和一個類型到每一個字段,如下是本次例子使用的topackagetutorial;messagePersonrequiredstringname=1;requiredint32id=2;optionalstringemail=3;en
21、umPhoneTypeMOBILE=0;HOME=1;WORK=2;messagePhoneNumberrequiredstringnumber=1;optionalPhoneTypetype=2default=HOME;repeatedPhoneNumberphone=4;messageAddressBookrepeatedPersonperson=1;有如你所見的,語法類似于C+或Javao讓我們分塊理解他們。waiting編譯你的ProtocolBuffer現(xiàn)在已經(jīng)擁有了.proto文件,下一步就是編譯生成相關的訪問類。運行編譯器protoc編譯你的.proto文件。.如果還沒安裝編譯器
22、則下載并按照README的安裝。.運行編譯器,指定源目錄和目標目錄,定位你的.proto文件到源目錄,然后執(zhí)行protoc-I=$SRC_DIR-python_out=$DST_DIRto因為需要使用Python類,所以-python_out選項指定了特定的輸出語言。這個步驟會生成addressbook_pb2.py©目標目錄。7.5ProtocolBufferAPI不像生成的C+和Java代碼,Python生成的類并不會直接為你生成存取數(shù)據(jù)的代碼。而是(有如你在addressbook_pb2.py見到的)生成消息描述、枚舉、和字段,還有一些神秘的空類,
23、每個對應一個消息類型:classPerson(message.Message):_metaclass_=reflection.GeneratedProtocolMessageTypeclassPhoneNumber(message.Message):_metaclass_=reflection.GeneratedProtocolMessageTypeDESCRIPTION=_PERSON_PHONENUMBERDESCRIPTOR=_PERSONclassAddressBook(message.Message):_metaclass_=reflection.GeneratedProtocolM
24、essageTypeDESCRIPTOR=_ADDRESSBOOK這里每個類最重要的一行是_metaclass_=reflection.GeneratedProtocolMessageTyp國過Python的元類機制工作,你可以把他們看做是生成類的模板。在載入時,GeneratedProtocolMessageType元類使用特定的描述符創(chuàng)建Python方法。隨后你就可以使用完整的功能了。最后就是你可以使用Person類來操作相關字段了。例如你可以寫:importaddressbook_pb2person=addressbook_pb2.Person()person.id=1234person
25、.name="JohnDoe"person.email="jdoe”phone=person.phone.add()phone.number="555-4321”phone.type=addressbook_pb2.Person.HOME需要注意的是這些賦值屬性并不是簡單的增加新字段到Python對象,如果你嘗試給一個.proto文件中沒有定義的字段賦值,就會拋出AttributeError異常,如果賦值類型錯誤會拋出TypeError。在給一個字段賦值之前讀取會返回缺省值:person.no_such_field=1#raiseAttributeErr
26、orperson.id="1234"#raiseTypeError更多相關信息參考(枚舉枚舉在元類中定義為一些符號常量對應的數(shù)字。例如常量addressbook_pb2.Person.WORK擁有值2。標準消息方法每個消息類包含一些其他方法允許你檢查和控制整個消息,包括:IsInitialized():檢查是否所有必須(required)字段都已經(jīng)被賦值了。_str_():返回人類可讀的消息表示,便于調試。CopyFrom(other_msg):使用另外一個消息的值來覆蓋本消息。Clear():清除所有元素的值,回到初識狀態(tài)。這些方法是通過接口Message實現(xiàn)的,更多消息
27、參考(7.5.3解析與串行化最后,每個ProtocolBuffer類有些方法用于讀寫消息的二進制數(shù)據(jù)(*SerializeToString():串行化,并返回字符串。注意是二進制格式而非文本。ParseFromString(data):解析數(shù)據(jù)。他們是成對使用的,提供二進制數(shù)據(jù)的串行化和解析。另外參考消息API參考(NoteProtocolBuffer與面向對象設計ProtocolBuffer類只是用于存取數(shù)據(jù)的,類似于C+中的結構體,他們并沒有在面向對象方面做很好的設計。如果你想要給這些類添加更多的行為,最好的方法是包裝(wrap)o包裝同樣適合于復用別人寫好的.proto文件。這種情況下,
28、你可以把ProtocolBuffer生成類包裝的很適合于你的應用,并隱藏一些數(shù)據(jù)和方法,暴露有用的函數(shù)等等。你不可以通過繼承來給自動生成的類添加行為。這會破壞他們的內部工作機制。7.6寫消息現(xiàn)在開始嘗試使用ProtocolBuffer的類。第一件事是讓地址本應用可以記錄聯(lián)系人的細節(jié)信息。想要做這些需要先創(chuàng)建聯(lián)系人實例,然后寫入到輸出流。這里的程序從文件讀取地址本,添加新的聯(lián)系人信息,然后寫回新的地址本到文件。#!/usr/bin/pythonimportaddressbook_pb2importsys#這個函數(shù)使用用戶輸入填充聯(lián)系人信息defPromptForAddress(person):p
29、erson.id=int(raw_input("EnterpersonIDnumber:")=raw_input("Entername:")email=raw_input("Enteremailaddress(blankfornone):")ifemail!="":person.email=emailwhileTrue:number=raw_input("Enteraphonenumber(orleaveblanktofinish):")ifnumber="&qu
30、ot;:breakphone_number=person.phone.add()phone_number.number=numbertype=raw_input("Isthisamobile,home,orworkphone?")iftype="mobile":phone_number.type=addressbook_pb2.Person.MOBILEeliftype="home":phone_number.type=addressbook_pb2.Person.HOMEeliftype="work":phone
31、_number.type=addressbook_pb2.Person.WORKelse:print"Unknownphonetype;leavingasdefaultvalue."#主函數(shù),從文件讀取地址本,添加新的聯(lián)系人,然后寫回到文件iflen(sys.argv)!=2:print"Usage:",sys.argv0,"ADDRESS_BOOK_FILE"sys.exit(-1)address_book=addressbook_pb2.AddressBook()讀取已經(jīng)存在的地址本try:f=open(sys.argv1,&qu
32、ot;fb")address_book.ParseFromString(f.read()f.close()exceptOSError:printsys.argv1+":Countopenfile.Creatinganewone."添加地址PromptFromAddress(address_book.person.add()寫入到文件f=open(sys.argv1,"wb")f.write(address_book.SerializeToString()f.close()7.7讀消息當然,一個無法讀取的地址本是沒什么用處的,這個例子讀取剛才創(chuàng)建
33、的文件并打印所有信息#!/usr/bin/pythonimportaddressbook_pb2importsys#遍歷地址本中所有的人并打印出來defListPeople(address_book):forpersoninaddress_book.person:print"PersonID:",person.idprint"Name:",ifperson.HasField("email"):print"E-mail:",person.emailforphone_numberinperson.
34、phone:ifphone_number.type=addressbook_pb2.Person.MOBILE:print"Mobilephone#:",elifphone_number.type=addressbook_pb2.Person.HOME:print"Homephone#:",elifphone_number.type=addressbook_pb2.Person.WORK:print"Workphone#:",printphone_number.number#主函數(shù),從文件讀取地址本iflen(sys.argv)!=2
35、:print"Usage:",sys.argv0,"ADDRESS_BOOK_FILE"sys.exit(-l)address_book=addressbook_pb2.AddressBook()#讀取整個地址本文件f=open(sys.argv1,"rb")address_book.ParseFromString(f.read()f.close()ListPeople(address_book)擴展ProtocolBuffer在你發(fā)不了代碼以后,可能會想要改進ProtocolBuffer的定義。如果你想新的數(shù)據(jù)結構向后兼容,而你的舊
36、數(shù)據(jù)可以向前兼容,那么你就找對了東西了,不過有些規(guī)則需要遵守。在新版本的ProtocolBuffer中:必須不可以改變已經(jīng)存在的標簽的數(shù)字。必須不可以增加或刪除必須(required)字段??梢詣h除可選(optional)或重復(repeated)字段??梢蕴砑有碌目蛇x或重復字段,但是必須使用新的標簽數(shù)字,必須是之前的字段所沒有用過的。這些規(guī)貝1(也有例夕卜(http:用。如果你遵從這些規(guī)則,舊代碼會很容易的讀取新的消息,并簡單的忽略新的字段。而對舊的被刪除的可選字段也會簡單的使用他們的缺省值,被刪除的重復字段會自動為空。新的代碼也會透明的讀取舊的消息。然而,需要注意的是新的可選消息不會在舊的
37、消息中顯示,所以你需要使用has_嚴格的檢查他們是否存在,或者在.proto文件中提供一個缺省值。如果沒有缺省值,就會有一個類型相關的默認缺省值:對于字符串就是空字符串;對于布爾型則是false;對于數(shù)字類型默認為0。同時要注意的是如果你添加了新的重復字段,你的新代碼不會告訴你這個字段為空(新代碼)也不會,也不會(舊代碼)包含has_標志。高級使用ProtocolBuffer不僅僅提供了數(shù)據(jù)結構的存取和串行化。查看PythonAPI參考(一個核心功能是通過消息類的映射(reflection)提供的。你可以通過它遍歷消息的所有字段,和管理他們的值。關于映射的一個很有用的地方是轉換到其他編碼,如X
38、ML或JSONo一個使用映射的更高級的功能是尋找同類型兩個消息的差異,或者開發(fā)出排序、正則表達式等功能。使用你的創(chuàng)造力,還可以用ProtocolBuffer實現(xiàn)比你以前想象的更多的問題。映射是通過消息接口提供的。waitingC+代碼生成waitingC+APIwaitingJava代碼生成waitingJavaAPIwaitingPython代碼生成本頁提供了Python生成類的相關細節(jié)。你可以在閱讀本文檔之前查看語言指導。Python的ProtocolBuffer實現(xiàn)與C+和Java的略有不同,編譯器只輸出構建代碼的描述符來生成類,而由Python的元類來執(zhí)行工作。本文檔描述了元類開始生效
39、以后的東西。ProtocolBuffer通過編譯器的"python_out=選項來生成Python的相關類。這個參數(shù)實際上是指定輸出的Python類放在哪個目錄下。編譯器會為每個.proto文件生成一個對應的.py文件。輸出文件名與輸入文件名相關,不過有兩處修改:擴展名.proto改為.py。路徑名的修改。如果你按照如下調用編譯器:protoc-proto_path=src-python_out=build/gensrc/tosrc/bar/to編譯器會自動讀取兩個.proto文件然后產(chǎn)生兩個輸出文件。在需要時編譯器會自動創(chuàng)建目錄,不過python_out
40、指定的目錄不會自動創(chuàng)建。需要注意的是,如果.proto文件名或路徑包含有無法在Python中使用的模塊名(如連字符),就會被自動轉換為下劃線。所以文件to會變成foo_bar_pb2.py。Note在每個文件后綴的_pb2.py中的2代表ProtocolBuffer版本2。版本1僅在Google內部使用,但是你仍然可以在以前發(fā)布的一些代碼中找到它。自動版本2開始,ProtocolBuffer開始使用完全不同的接口了,從此Python也沒有編譯時類型檢查了,我們加上這個版本號來標志Python文件名。包Python代碼生成根本不在乎包的名字。因為Python使用目錄名來做包
41、名。消息先看看一個簡單的消息聲明:messageFoo。ProtocolBuffer編譯器會生成類Foo,它是tobuf.Message的子類。這個實體類,不含有虛擬方法。不像C+和Java,Python生成類對優(yōu)化選項不感冒;實際上Python的生成代碼已經(jīng)為代碼大小做了優(yōu)化。你不能繼承Foo的子類。生成類被設計不可以被繼承,否則會被打破一些設計。另外,繼承本類也是不好的設計。Python的消息類沒有特定的公共成員,而是定義接口,極其嵌套的字段、消息和枚舉類型。一個消息可以在另外一個消息中聲明,例如messageFoomessageBar在這種't#況下,Bar類
42、定義為Foo的一個靜態(tài)成員,所以你可以通過Foo.Bar來引用。字段對于消息類型中的每一個字段,都有對應的同名成員簡單字段如果你有一個簡單字段(包括可選的和重復的),也就是非消息字段,你可以通過簡單字段的方式來管理,例如foo字段的類型是int32,你可以:message.foo=123printmessage.foo注意設置foo的值,如果類型錯誤會拋出TypeError。如果foo在賦值之前就讀取,就會使用缺省值。想要檢查是否已經(jīng)賦值,可以用HasField(),而清除該字段的值用ClearField()。例如:assertnotmessage.HasField("foo&quo
43、t;)message.foo=123assertmessage.HasField("foo")message.ClearField("foo")assertnotmessage.HasField("foo")簡單消息字段消息類型工作方式略有不同。你無法為一個嵌入消息字段賦值。而是直接操作這個消息的成員。因為實例化上層消息時,其包含的子消息同時也實例化了,例如定義:messageFoooptionalBarbar=1;messagebaroptionalint32i=1;你不可以這么做,因為不能做消息類型字段的賦值:foo=Foo()foo.bar=Bar()#WRONG!而是可以直接對消息類型字段的成員賦值:foo=Foo()assertnotfoo.HasField("bar")foo.bar.i=1assertfoo.HasField("bar")注意簡單的讀取消息類型字段的未賦值成員只不過是打印其缺省值
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 不動產(chǎn)交易合同書樣本(2024版)
- 2024年版無子女離婚合同法律范本版B版
- 2024年企業(yè)法律風險防范與合規(guī)咨詢服務合同匯編3篇
- 2024某互聯(lián)網(wǎng)公司與某內容提供商關于2024年內容服務合同
- 專業(yè)場地考察服務協(xié)議2024年版版B版
- 2024年版教育資源共享平臺開發(fā)與運營合同
- 2024年酒店服務質量改進與投訴處理合同
- 泵站電工知識培訓課件
- led燈珠購銷合同(2024版)
- 2024年酒店燈具采購協(xié)議
- 眼內炎患者護理查房
- 電工維修培訓資料 維修電工技術學習 維修電工常識 電工培訓ppt課件
- 撲克牌24點練習題大全
- 螺絲英文簡稱
- 15MW風力發(fā)電機
- 正面管教 讀書分享(課堂PPT)
- 教練技術CP理論PPT課件
- 產(chǎn)品生命周期曲線(高清)
- 機械工程學報標準格式
- 東南大學文科揭榜掛帥重大平臺績效考核表
- 鉑銠合金漏板.
評論
0/150
提交評論