[Go] 閱讀心得 不負責任翻譯 Golang Frequently Asked Questions (FAQ) PART3


https://golang.org/doc/faq

官方FAQ 提供一些有趣的資訊,很認真的試圖都理解一下,由於內容太多,拆成幾個部分來看。

PART3這裡有Values  Writing Code  Pointers and Allocation  Concurrency



--Values--


Why does Go not provide implicit numeric conversions?

要考量的問題很多,轉換後是否為正數?值會多大?會不會溢位?是否可用?

自動轉換數字型態所帶來的混亂大過好處,沒有特別設計的compile架構很難滿足這個機制。

對GO而言即使64-bit的系統,int也不等於int64的型態。



Why are maps built in?

如strings一樣重要,這種結構可以滿足廣大的定義需求。

map結構,雖然語意寫法稍微不方便了點,但complie的速度快,這應該是可被接受的合理平衡點。



Why don’t maps allow slices as keys?

map 裡面的查找,需要equality 運算子(我不清楚這個equality是什麼)。

對於slice是沒有equality 運算子的,但array,和struct有,所以可以當作map的keys。(我的天呀)

(會問這種問題,真是超乎想像)



Why are maps, slices, and channels references while arrays are values?

為什麼map, slices, and channels 是參考,arrays 是數值。

我的理解是在講call by references 的 references,還有 call by value的value。

map, slices, and channels 是指標,所以不可能生出非指標型態的實體,GO也掙扎的想把array做成這樣。

但會有一些很複雜的作用,所以GO放棄,還是維持value的可用性較高。(這部分看得不是很懂)



 --Writing Code-- 

How are libraries documented?

godoc 提供的功能豐富,可以滿足文件化的需求。
Is there a Go programming style guide?
請參考Effective GO https://golang.org/doc/effective_go.html

使用gofmt,可以大部分自動解決coding style 的問題。(真的是我看過最方便的自動format的套件)



How do I submit patches to the Go libraries?(如果想上補丁給GO,略)




Why does “go get” use HTTPS when cloning a repository?

為了防止中間人攻擊,所以這樣的方式去clone repo。

這邊介紹了一些連線是較安全的設定(略)。



How should I manage package versions using “go get”?

go get 無法進行版本控制這件事。

建議先載下來到自己電腦,複製一份使用

gomvpkg,dep 這兩個東西可以有所幫助。(個人推薦govendor)




--Pointers and Allocation--

When are function parameters passed by value?

就像C語言,GO 在function 傳遞變數,都是passed by value。

所以傳遞int,就會複製一份int的value。

傳遞pointer,只會複製一份pointer出來,但是不會複製pointer所指的value。

傳遞時要傳原本的type,還是傳pointer,詳細看後面的FAQ

傳遞map或slice,是傳遞pointer,因為底層是pointer。

如果傳遞的是interface,就會複製interface的value,如果interface裡面包struct,會複製struct的value,裡面包pointer,就會只複製pointer但不複製value。



When should I use a pointer to an interface(看不懂)?

GO説99.9%的時候不要,pointer to an interface。(但我看不懂說明)



Should I define methods on values or pointers?

到底function 接受的對象要是values,還是pointer,需要根據很多考量做決定。

如果接收的部分以後可能會改變,建議是採用pointer。

接收的部分是slice會map的型態,會表現得像refference,如果傳進來的slice長度被改變,這個時候又會表現得像pointer。

如果傳指標,function內去改它,原本的內容就會改,如果是value,function內有異動不會影響原本的。

GO 建議如果是basic types, slices, and small structs,傳value沒關係,成本很小,並且程式碼乾淨。



What’s the difference between new and make?

make 和 new 的差異請參考effective go。

(effective go 的解釋,理解如下)

使用new 所做的『allocate』並不像其他語言會做初始化記憶體的動作,它做的是zero type,zero type 是將該type給予初始值,如int就是0,string就是空字串,pointer就是nil。做了zero type 給予一個新的指標指向它,並回傳該指標。

make 就不同,slices、map、channels 就需要使用make,初始化記憶體分配,如make([]int, 10),系統就需要配出10個記憶體空間出來。

因為印象中,使用slice我都沒有先make,所以去查了一下, var s []int 等同於 s := make([]int, 0),所以這可以被允許的。

不過map就無法這樣子,有人解釋因為map需要額外的空間做bookkeeping,所以一定要initailize memory?

這裡我不太懂的是如果把map塞進某個struct,當我在使用這個struct好像不用額外make,也活得好好的?



What is the size of an int on a 64 bit machine?

Go 1.1版後,int 也是以bit-64的型態呈現。

GO 的float預設是float64,如 a := 2.34 ,預設會是float64



How do I know whether a variable is allocated on the heap or the stack?

不用管allocate是放在stack或者heap,在Go裡面不用在意,Go compiler會負責。

以下找到很不錯的說明stack 和heap的文章
http://nwpie.blogspot.com/2017/05/5-stack-heap.html
https://www.codeproject.com/Articles/76153/Six-important-NET-concepts-Stack-heap-value-types#Stack and Heap



Why does my Go process use so much virtual memory?

GO 就是會擁有一塊虛擬記憶體做分配使用,這並不會影響其他process的記憶體使用。(感覺沒有正面回答問題)

可以用Unix top指令查閱—> RES (Linux) or RSIZE (Mac OS X) 。




--Concurrency--

What operations are atomic? What about mutexes?

GO 尚未完全定義好關於記憶體的完整性,請參考 The Go Memeory Model。

考慮mutex這包的package,GO希望開發者們可以善用,並且使用較高級的技巧,讓每個gorutine保持單一負責的部分。

永遠不要用分享記憶體來作為溝通用途,而是用溝通來彼此分享記憶體。



Why doesn’t my multi-goroutine program use multiple CPUs

早期GO的版本預設只有使用到一顆CPU核心,1.5版後預設為多顆核心。

注意,並發跟並行是兩回事。



Why does using GOMAXPROCS > 1 sometimes make my program slower?

實際程式會不會並行處理,還是看你程式怎麼寫,如果程式都是需要依序執行,設定多核去跑是沒作用的。

multiple threads 彼此溝通上所耗費的時間,這部分包含content switch,遠勝於computing的時間。

所以GO對於並行處理並沒有那麼看好,即時產生了很多的gorutine,也不一定會並行處理,設定了多核反而變慢是有可能的。



Why is there no goroutine ID?

goruntine 沒有名字,或特別獨特或可識別的部分,都是匿名的,有人提問這個是為了想進入與控制gorutine。

匿名是做並行的其中一個關鍵,gorutine都是匿名的所以整個GO都可利用。

有名字或者有識別的結構,反而會限制了並發處理。

如果有個特殊或者可是別的gorutine,會開始有很多模組圍繞著這個特殊的gorutine建立,如此一來,這個goruntine再也無法被共享處理。

其他語言往往有個主線程,或者說如果有個main goruntine,很容易因為操作這個主要的thread(/gorutine),可能不小心亂用,而導致系統崩潰。

再說一次,並發不代表並行。




Created Date : 2018/08/10

Last Updated Date : 2018/08/10

留言

這個網誌中的熱門文章

[Go] 型態轉換 type convert

[Go] Golang用法 package import 前面的底線

[Go] 指標 pointer with golang