2014-11-11 3 views
5

. Tutti gli esempi di prototipi iniziano a numerare i loro campi in uno.I campi dei file .proto iniziano da zero?

ad es. https://developers.google.com/protocol-buffers/docs/proto#simple

message SearchRequest { 
    required string query = 1; 
    optional int32 page_number = 2; 
    optional int32 result_per_page = 3; 
} 

Se può essere utilizzato zero, farà alcuni messaggi uno o più byte più piccola (cioè quelli con uno o più numeri di campo 16).

Come la chiave è semplicemente una codifica varint di (fieldnum < < 3 | fieldType) non riesco a vedere subito perché non devono essere utilizzati a zero.

C'è un motivo per non iniziare la numerazione dei campi a zero?

+1

Stavo per fare questa domanda perché noi come programmatori siamo abituati a partire da zero. Grazie per averlo chiesto! – Sericaia

risposta

5

Un motivo molto immediato è che i numeri di campo pari a zero vengono respinte dal protoc:

test.proto:2:28: Field numbers must be positive integers. 

Quanto al motivo per buffer protocollo è stato progettato in questo modo, posso solo immaginare. Una buona conseguenza è che un messaggio pieno di zeri verrà rilevato come non valido. Può anche essere usato per indicare "nessun campo" internamente come valore di ritorno nell'implementazione dei buffer di protocollo.

+0

Ah, non me ne ero reso conto, perché uso la mia libreria JS per lavorare con i protobufs. Farò anche zero numeri di campo illegali in questo. – fadedbee

+1

Il vecchio codice proto1 (mai rilasciato pubblicamente) conteneva commenti che suggerivano che il tag zero poteva essere usato per indicare un errore, sebbene non abbia mai visto il codice che in realtà lo ha fatto. Forse era una funzionalità molto presto rimossa. In ogni caso, la proibizione dei campi a numero zero è rimasta, e probabilmente è utile in quanto cattura le persone che fanno irrimediabilmente a zero i loro messaggi protobuf e si aspettano che vengano ancora correttamente analizzati (il che accade molto!). –

1

Assegnazione Tag

Come potete vedere, ogni campo nella definizione messaggio ha un tag numerata unica. Questi tag vengono utilizzati per identificare i campi nel formato binario dei messaggi e non devono essere modificati una volta che il tipo di messaggio è in uso. Tieni presente che i tag con valori compresi nell'intervallo compreso tra 1 e 15 richiedono un byte da codificare, incluso il numero identificativo e il tipo del campo (puoi trovare ulteriori informazioni a riguardo in Codifica buffer del protocollo). I tag compresi tra 16 e 2047 richiedono due byte. Pertanto, è necessario prenotare i tag da 1 a 15 per gli elementi dei messaggi che si presentano molto frequentemente. Ricordarsi di lasciare spazio per gli elementi che si verificano di frequente e che potrebbero essere aggiunti in futuro.

Il numero di tag più piccolo che è possibile specificare è 1 e il più grande è 2 -1 o 536,870,911. Non è inoltre possibile utilizzare i numeri da 19000 a 19999 (FieldDescriptor :: kFirstReservedNumber tramite FieldDescriptor :: kLastReservedNumber), poiché sono riservati all'implementazione del protocollo di buffer - il compilatore del buffer del protocollo si lamenterà se si utilizza uno di questi numeri riservati nel proprio .proto. Allo stesso modo, non è possibile utilizzare tag precedentemente riservati.

https://developers.google.com/protocol-buffers/docs/proto

Proprio come dice il documento, 0 non può essere rilevata.