當你第一次定義Protocol Buffer的訊息的時候,你肯定會給訊息設定一套規則需求,但是隨著時間的推進,你的業務可能會發生了變化,與此同時,你的Protocol Buffer訊息型別的需求也會隨之變化, 也就是說:有一些欄位可能會發生變化,可能會添加一些欄位,也可能會洗掉一些欄位,但是可能有很多程式正在使用/讀取你的Protocol Buffer的訊息,但是它們沒法都隨著需求進行更新,所以,在你對源資料進行演進的時候,一定不要引起破壞性變化,否則其它的程式可能就無法正常作業了, 主要有這兩種情景:
- 向前兼容變更:使用新的.proto檔案來寫資料 --- 從舊的.proto檔案讀取資料
- 向后兼容變更:使用舊的.proto檔案來寫資料 --- 從新的.proto檔案讀取資料
- 不要修改任何現有欄位的數字(tag)
- 你可以添加新的欄位,那些使用舊的訊息格式的代碼仍然可以將訊息序列化,您應該注意這些元素的默認值,以便新代碼可以與舊代碼生成的訊息正確互動,類似的,新代碼所創建的訊息也可以被舊代碼決議:舊的二進制在決議的時候會忽略新的欄位,
- 欄位可以被洗掉,只要它們的數字(tag)在更新后的訊息型別中不再使用即可,你也可以把欄位名改為使用“OBSOLETE_”前綴而不是洗掉欄位,或者把這些欄位的數字(tag)進行保留(reserved),以免未來其它開發者不訊息使用了洗掉欄位的數字,
- 對于資料型別的變化,例如int32到int64,string到bytes等等,可以參考官方檔案:
https://developers.google.com/protocol-buffers/docs/proto3#updating, 但是建議還是盡量不要去修改欄位的資料型別,
添加欄位
原來的proto是這樣的:對欄位重命名
現在我把name這個欄位的名改成了full_name,而它的數字不變:洗掉欄位
現在我又把full_name欄位洗掉了:使用OBSOLETE
之前說了,可以把欄位名改為 OBSOLETE_欄位名 來代替洗掉欄位,但是這樣做的缺點就是:你還是需要把這個欄位的值計算出來,我還是建議使用reserve的方式進行洗掉欄位的管理,Reserved
- 你可以保留欄位的數字tag和欄位名;
- 但是不可以在同一行陳述句里混合reserved數字tag和欄位名,應該分成兩個陳述句:
- 保留欄位數字tag的目的就是防止數字tag被重復使用;
- 而保留欄位名的目的就是防止出現一些程式bug;
默認值
默認值在更新Protocol Buffer訊息定義的時候有很重要的作用,它可以防止對現有代碼/新代碼造成破壞性影響,它們也可以保證欄位永遠不會有null值, 但是,默認值還是非常危險的:- 你無法區分這個默認值到底是來自一個丟失的欄位還是欄位的實際值正好等于默認值,
- 需要保證這個默認值對于業務來說是一個毫無意義的值,例如 int32 pop(人口)默認值就可以設定為-1,
- 再就是,可能需要在你的代碼里來做一些對默認值的判斷,從而進行處理,
列舉
enum同樣可以進化,就和訊息的欄位一樣,可以添加、洗掉值,也可以保留值, 但是如果代碼不知道它接收到的值對應哪個enum值,那么enum的默認值將會被采用, 例如這個enum:轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/40869.html
標籤:Go
上一篇:Go語言 二分查找演算法的實作
下一篇:Go語言學習之goroutine
