golang的一些體會
1. 接口變量肯定對應(yīng)一種具體類型,參考java的接口與實現(xiàn)。
2. 如果使用接口類型變量存儲對象,那內(nèi)存里會存兩份內(nèi)容:實際類型、接口類型(含接口中的函數(shù)指針列表)。
- 其實這里的函數(shù)指針列表類似于C++的虛函數(shù)表。
- 因為go的鴨子類型,所以接口變量必須記錄接口中函數(shù)在對象的實現(xiàn),否則無法找到,或者查詢太慢。
3. gin 開發(fā)web項目超級簡單,前提是懂HTTP協(xié)議。 一個有意思的是支持一個進程占用多個端口,這個是之前沒有想過的。
4. grpc + protobuf + interceptor + lb 已經(jīng)具備了微服務(wù)的一些基本功能。
5. etcd v3 已經(jīng)與 v2完全不一樣了,v2還是zk、redis的思路,v3則把租約單獨抽取出來,并取消了目錄格式(雖然表現(xiàn)上還是支持),還有watch不像zk那么弱(zk的通知不含數(shù)據(jù),需要主動查詢,期間可以漏掉中間的變動,或者存在不一致的情況)。
6. go-zero 開發(fā)微服務(wù)的確方便,提供命令和goland插件,基于pb一鍵生成代碼,清晰易懂。插件豐富。嗯嗯,目前還沒搞定既發(fā)布服務(wù)也訂閱服務(wù)的情況,有時間研究下。
7. dubbo-go 也不錯,提供了專門的命令。
8. 在某些方面上,go非常接近C和linux,如 os.Signal、exec等。
9. go的error是接口,對象可以是直接錯誤類型( errors.New("直接錯誤") ),也可以是封裝錯誤類型( fmt.Errorf("我是封裝的!%w", err) ),后者其實是一棵樹。
- 因為存在封裝,所以有時候error不能直接使用 == 來判斷,需要使用 errros.Is 來判斷。
- 因為存在封裝,所以可以使用 errors.As 來提取指定類型的錯誤。
10. 直接提供了操作切片的slices工具包,這個是新增的吧? 非常有用!比如壓縮Compact、清理冗余空間Clip、判等Equal、追加Concat、逆向Reverse、插入Insert、排序Sort、二分查找等。
11. reflect分為兩塊,Type和Value。
- Type可以獲取更底層的Kind(),比如別名時 type IA int32; type IB int32;,它們的Type肯定不一樣,但Kind一樣。
- Value又分為可操作和不可操作的(指針類型可操作,其他類型因為是值傳遞導致無法修改原值),可操作的需要Elem才能操作。另外,還提供了CanXxx用于判斷是否支持設(shè)置相應(yīng)類型的數(shù)值。
12. 新版本 for 的變量每次都是新分配的空間,所以現(xiàn)在不會出現(xiàn)因為循環(huán)變量導致的閉包問題了。(為了兼容老版本,建議還是寫 fun(x){}(x) 這種)
13. struct可以直接==比較 -- 無論是直接創(chuàng)建的還是new出來的(當然new的需要解引用一下,否則就成了指針判等)
14. go協(xié)程其實無所謂父子協(xié)程,所以也不存在捕獲子協(xié)程的異常一說。不像父子進程、線程。
15. 因為14,所以只能在當前協(xié)程里捕獲異常。
2024.08.15:漏了一點,etcd的mvcc和postgresql幾乎一樣,由此導致的問題(體積膨脹)也是類似的。
浙公網(wǎng)安備 33010602011771號