1. 程式人生 > >golang的坑(持續更新中....)

golang的坑(持續更新中....)

使用golang開發新專案有一段時間了,現在逐漸對go有點失望了,但還好沒有絕望。

最開始草草翻閱《go語音程式設計》( 許式偉)時,最讓我眼前一亮的其實並不是協程(這個已經聽了太多太多…),而是其中對json的marshal和unmarshal,然後就瞭解到go可以對struct成員設定tag的特性。簡單思考了一下,發現這個特性如果能夠移植到我們現在的python程式碼中會讓程式碼看起來更優雅一點。

隨著專案的進行,對go的特性逐漸有了更深入的瞭解,然後越來越覺得之前有些看起來很棒的地方其實並沒有想象中的那麼好了。

現在開噴

  • 由於golang是一門強型別語言,所以在json unmarshal時,如果struct的定義裡不是指標,那麼是無法區分到底是接收到了一個預設值還是json包中沒有這個引數。這個其實問題也不算太嚴重,只是程式設計時需要小心的地方之一。

  • 由於用慣了peewee,導致對golang的幾個orm實現並不是很滿意。在peewee中,model背後隱藏了一個dirty成員,這個成員可以記錄你對那些列進行了修改,各種黑魔法(比如修改物件成員時可以通知物件)也使python實現的orm用起來十分自然、靈活。

  • go雖然說為了保持語法的簡單,使用了極少的關鍵字,然而實際上,為了實現某些功能,又隱藏了一些奇奇怪怪的東西在裡邊:比如iota,以_test.go結尾的測試程式碼,link的時候可以指定某些變數的值….不知道隨著學習的深入,還會有哪些奇怪的東西在某一天忽然跳出來。不過想想應該會比c++少吧 :)

  • 為了不讓使用者隨意使用go routine id做些事情,於是把go routine id給隱藏起來….官方的說法時,使用goroutine local storage時,萬一忘了清理,就會很麻煩。這裡有一個比較好用的gls庫:

    tylerb/gls

  • 最值得吐槽的就是官方庫的實現了吧。log包幾乎沒有一點實用價值,相比於python logging包中的各種handler、formatter,你會深深覺得這個東西寫的太隨意。這裡推薦一個覺得比較好用的log包:inconshreveable/log15。後續我大概有可能會根據這個實現一個log16吧 : )

  • 對於go新穎的包匯入方式….最終還是無法避免不同版本之間的相容問題,於是搞了一個vendor。但這並不算完,曾經編譯一個專案的時候提示找不到一個包,然後跑到對應的git倉庫上一看,作者說”have moved to xxxx”…

  • 假設你的專案中用到了一個開源庫A,並且用到了另外一個開源庫B,其中B也用到了A,但是這個A是放置在B的vendor中的,那麼在編譯你的程式碼時,golang其實會把這兩個當做不同的包編譯進去的。好了,這其實不算是什麼問題,但是萬一A用到了另外一個包C中的一個全域性變數!! GG

說點好的

噴了這麼多,golang裡邊的很多包有時候還是會給人帶來很意外的驚喜的,從設計上或實現的功能上,讓人眼前一亮。

  • golang.org/x/net/trace:你可以通過建立一個trace物件,然後使用traceObj.LazyPrintf記錄一些日誌資訊,同時啟動預設的http server,這樣你就可以在http://default-server/debug/requests這個頁面檢視所有正在活動中和已關閉的trace物件及其資訊。