Go 問答彙總篇 二

繼上篇 Go 問答彙總,已通過去了一個多月。今天彙總下近一個多月我關於 Go 的回答。python

粗略數了一下,一個多月的時間裏,大約回答了 18 個與 Go 有關的問題,問題主要是來源於 segmentfault 和 zhihu 兩個平臺。後面但願加入更多平臺,如 stackoverflow、github 的感興趣主題。git

最近在寫一個小工具,準備用於幫助本身回答不一樣平臺的問題,同時也便於每月的問題彙總。寫的有點慢,但願月底能夠完成。github

正文部分開始。golang

golang中如何將redis取出的map[string]string數據解析到目標struct中?web

主要和反射相關。redis

問題主要是關於 map 中若是存在日期字符格式串,如何解析到 time.Time 類型成員中,而對於結構體而言,reflect.Kind() 返回的只能說明字段類型是 struct,並不能肯定真正的類型,這時能夠用 Go 的 switch type 類型查詢語法實現。數據庫

補充一點,在回答中沒有提到的。json

在實現 map 到 struct 的通用方法時,咱們比較容易想到支持基礎類型,但對於結構體類型而言,可能性太多,如何更靈活地解決問題?我以爲,可經過鉤子方式實現,即若是自定義類型須要支持 map 到 struct 的轉化,可經過在自定義類型上增長鉤子方法實現,好比 UnmarshalMap。如何實現可參考下 encoding/json。segmentfault

固然,這個工做已經有人作了,參考 github 上的包,mitchellh/mapstructure。前面說的 Hook 也是支持的。微信

golang 怎麼優雅的實現錯誤碼?

Go 對錯誤處理有一套本身的理念。這個問題,我只是簡單回答了一下,簡單的思路,我定義了用戶級別錯誤和系統級別錯誤。上篇問答彙總也會相似問題。

golang何時該返回error,何時panic?

個人建議是,發生的 error 是否已經嚴重影響服務邏輯,若是在預判以內的錯誤,咱們就應該 return error,記錄日誌,並不須要人工干預才能恢復,不然建議 panic。

舉個例子,在通常狀況下,服務啓動時,須要進行完善的初始化工做,確認各個組件的運行正常。若是初始化都失敗了,那就沒有必要繼續向下走了,應該 panic 趕忙提示。

Golang time 如何實現的?

問題標題看着挺大,其實題主關心是幾個核心常量之間的轉化關係。主要是三個時間,分別 unix 時間、wall 時間和 absolute 時間。這裏面有個相對重要的轉化公式,在須要考慮平潤年的時候稍微有點複雜。

很少介紹了,具體本身看回答吧。

golang 中時候用指針何時用普通對象?

其實就兩點,一是若是數據結構比較大,建議採用指針,不會發生值拷貝。二是若是須要修改結構的話,必須用指針。固然若是是引用類型,好比 chan、slice、 map,就不用考慮這個問題了。

Golang中的make(T, args)爲何返回T而不是*T?

make 針對的是 Go 的引用類型,即 chan、slice 和 map,而 new 針對的指針。引用類型爲何 make 不是返回指針呢?這樣一說好像和上個問題有點相似了,固然由於引用並不存在值類型的那些問題。

在循環中 append map 到 map slice,map slice 中的數據所有爲最後一次 append 的數據

與上一個問題知識點相似,map 是引用類型,即便 slice 經過 append 賦值了多份 map 變量,可是其內部指向是同一個地址。

golang中哪些引用類型的指針在聲明時不用加&號,哪些在函數定義的形參和返回值類型中不用*號標註

與前面問題相似,具體看回答。

個人理解,從這裏向前數的四個問題,考察知識點基本相似,簡單點說,就是 make 和 new 和問題。本質上講,就是變量內部就是什麼的問題。

爲何 go語言的slice內部函數那麼少?

說實話,我也不明白爲何 Go 團隊沒有像爲 string 類型那樣爲 slice 提供相應的標準庫幫助 slice 更方便的操做。但其實,即便沒有這樣的包, slice 常見的各類增刪改查也是能夠實現,就是稍微有點 hack。具體如何實現,看看個人問答吧。

golang 等值比較是否是直接比較地址呢?

首先要說 Go 的等值比較比較的是值,而不是地址。Go 中變量的可比較類型是內置的,基本全部類型均可以進行比較,包括 interface 和 struct。兩個變量可比較的提早必須是相同類型。但有一點須要說明的是,interface 是不肯定的類型,全部它不但會比較值,還有比較具體的類型。

回答完這個問題後,我忽然想起前段時間比較兩個同類型結構體時還用了反射包中 reflect.DeepEqual 方法,真的是浪費資源啊。

golang 中如何禁止一個導出類型直接構造,必須經過new函數來構造?

其餘的 oo 語言實現題主要求是很是簡單的,只要定義相應的私有成員屬性並經過構造函數控制輸入的參數便可。

那麼 Go 該如何實現呢?其實也很簡單,思路與 oo 是相似的。只是咱們把 oo 語言中的構造函數換成了 Go 中的工廠方法,私有變量變成了 Go 包級別的私有成員屬性。咱們只須要經過定義指定的可導出的工廠方法建立實例便可。

入門,進階GO語言,有什麼好的書籍推薦?

我從入門、中級到進階三個階段推薦了幾本書。有興趣的朋友,具體查看回答吧。

如何評價 Go 標準庫中新增的 plugin 包?

這個問題的回答,我是先學先買的。看了 medium 中幾篇關於 plugin 使用案例的文章,總共花了大概三四小時。plugin 包使 Go 是能夠實現動態模塊加載的能力,能夠在不用從新編譯主程序的狀況下加入新功能。這是有必定的價值的。

但 plugin 包也存在一些問題,使用起來會用一些限制因素。但若是咱們清楚地瞭解,仍是能拎的清咱們應該在什麼場景下使用它。具體有啥限制,查看回答吧。

go build 如何隱藏全局靜態字符串變量?

這個問題,我並無找到啥好辦法,能想到的就是經過加密解密的方式解決。固然,其實在真實的項目中,咱們能夠經過引入外部服務實現,好比 k8s 的配置加密功能,使用 ectd 管理配置等。

go語言中, 空的死循環與永遠阻塞的chan細節上有什麼差別?

Goroutine 是搶佔式的,這不一樣於傳統的協程模型。但它又不是徹底的搶佔式,單核的狀況下,仍是須要 CPU 主動出入資源的,而空死循環將會一直佔用着 CPU,對資源的浪費嚴重,而 chan 阻塞會出讓 CPU 資源,實現併發執行。這應該是二者最大的不一樣吧。

除了通常的 chan 實現阻塞,問答還介紹一些其餘方式,也能夠實現相似的效果。感興趣的朋友可查看回答。

Golang中fmt.Println和直接println有什麼區別?

println 主要是 Go 本身使用,好比源碼、標準庫等,而 fmt 纔是給 Go 開發人員使用的。並且要提的是 println 不能保證兼容性,可能在將來的某一天就不存在了,但 fmt 中的函數就不存在着這樣的問題。

固然,二者的使用和效果上也是有區別的,如 println 輸出是到標準錯誤的,而非標準輸出。

如何閱讀Golang的源碼?

這個回答是個大工程,零零碎碎花了我差很少三個星期的時間。什麼緣由呢?

我提了一個閱讀源碼的思路,分紅了大概三步,大體分別是,瞭解使用、熟悉架構和剖析原理。我最近在思考是否本身也開始剖析源碼,因而決定先以第一步入手,把 Go 的源碼整個擼一篇,大概瞭解涉及了的內容和它們的用途。總共涉及四十多個部分,因而花的時間就比較長。

第一步,瞭解使用這一塊,有些部分達到了解使用,可是有些部分只是達到了解的層次。若是要完整閱讀源碼,很難,但大概閱讀仍是可行的。準備等等合適時機啓動系統的源碼閱讀的計劃。

golang數據庫操做的時候,須要go func()嗎?跟python異步操做yield有什麼不一樣?

上篇 Go 問答彙總篇 也有相似問題。個人理解,使用 go func 的前提是必須有可並行執行的任務,這是一個重要前提。

不少時候,你們學 Go 都是衝着 Go 的併發來的,結果學以後發現壓根用不上,很鬱悶啊,總以爲哪裏用的不對,不該該是這樣的。通常的業務開發,特別是 web 的業務開發,使用併發的場景確實很少。而併發性能的問題,服務框架已經幫助咱們實現了,徹底沒有插手機會,要想真正學會併發,不能只是天天的增刪改查。

彙總完畢!回答若有錯誤,歡迎你們指正。最後,感謝閱讀,彙總篇彷佛是比較枯燥的!


波羅學的微信公衆號
相關文章
相關標籤/搜索