[Go] 閱讀心得 不負責任翻譯 Golang Frequently Asked Questions (FAQ) PART4 END
https://golang.org/doc/faq
官方FAQ 提供一些有趣的資訊,很認真的試圖都理解一下,由於內容太多,拆成幾個部分來看。
PART4這裡有
Functions and Methods Control flow Packages and Testing Implementation
Performance Changes from C
--Functions and Methods--
Why do T and *T have different method sets?接收到型態T的對象,有型態T所有的method,但如果是接收到型態*T,則會擁有型態T和型態*T的所有method。
如果interface裡面包含*T,那麼操作的行為會是pointer,如果是T,那操作的行為只能是value的處理方式。
如果是傳value,copy值之後,就跟原本被copy的部分沒關係了。
What happens with closures running as goroutines?
func main() {
done := make(chan bool)
values := []string{"a", "b", "c"}
for _, v := range values {
go func() {
fmt.Println(v)
done <- true
}()
}
// wait for all goroutines to complete before exiting
for _ = range values {
<-done
}
}
這個範例是在學GO蠻經典的例子,結論是永遠不要在gorutine裡面直接使用外面的變數。因為goruntine宣告後並不是馬上建立的,可能等一下才建立,以及複數個gorutine建立起來可能沒有順序性,此時外面的變數已經不知道跑到哪裡去了。
有兩個比較直觀的解法,一個是每次都直接將變數傳入goruntine的function。
一個是傳入之前都先copy一份。(這個感覺跟每個與scope處理的範圍有關,比較不直覺。)
--Control flow--
Does Go have the ?: operator?Go 沒有問號冒號的運算符號,請愛用if else 達成你的目標。
--Packages and Testing--
How do I create a multifile package?
在package的檔案可以分成多個沒關係,對於外面來使用都會視為同一檔案,並且不需要額外宣告或引用。
How do I write a unit test?
在單一檔案建立有 _test.go,參考go test,GO 為unit test有所準備。
Where is my favorite helper function for testing?
GO 有一包testing的package專門處理測試,但go裡面沒有斷言(這裡的斷言是斷value落在哪裡,而不是型態的斷言)。
過去在其他語言有發現斷言的結果有問題,最常被舉例的就是判斷『質數』的問題,2、3、5、7或2、4、8、16,跑到2就報錯了,後續往往沒有測到。
GO 的理念是將測試結合在這裡語言裡面,而不需要額外的測試框架來滿足測試需求。
測試的寫法可以參考https://golang.org/src/fmt/fmt_test.go
Why isn’t X in the standard library?
會出現在GO標準庫的libaray,是在執行期間,或需要配合作業系統,格式或協定轉換,或者go常用的基本函式的內容。
如http、io、json、xml 等等,但這沒有一個絕對的標準,完全是視今日所需。
往後的新原始碼會頃向放在外面,而非內建的標準庫,因為go的開發為了保證向下相容性,所以越多東西放進標準庫,越需要顧忌向下相容的保證。
--Implementation--
What compiler technology is used to build the compilers?
原本的gccgo是用c++ 寫成的,gc是用c寫成的。
不過後來1.5版以後,go的compillier是用go寫出來的(超酷!)。
How is the run-time support implemented?
原本run-time的編譯是用C寫成的,承上已經改為用GO寫出來的。
如果要用c語言的lib,gccgo還是可以幫忙做這件事情。
Why is my trivial program such a large binary?
即使只是用了C語言印出hello world,也要花750KB,這件事情在GO裡面印出也要花1MB以上。
原因是某些小東西看似不起眼,但他的靜態link,在run-time的動態型態,reflect,panic trace都要花費空間和資源做處理。
Can I stop these complaints about my unused variable/import?
未使用的變數可能造成錯誤(被誤用?),以及拖慢編譯和運行的速度,所以GO拒絕未使用的變數出現在裡面。
犧牲短期的便利,造成長期的效率和乾淨性是可以被接受的。
可以把他從error調整成warning層級嗎?GO拒絕,況且對於GO來說,編譯並沒有warning,只有error。(WOW WOW WOW ! 這令人驚訝)
如果值得警告,就值得去修理,若不值得修理,警告就只是對於編譯器的一種干擾,所以只有error!(霸氣…)
(下面那段我不太懂,略)
Why does my virus-scanning software think my Go distribution or compiled binary is infected?
GO的編譯檔被防毒軟體被誤認中毒是常發生的,尤其是在windows,這些編譯軟體常不認識GO。
請向你的防毒軟體公司回報bug吧。
--Performance--
Why does Go perform badly on benchmark X?(大部分不是很懂)大概是說有些benchmark測試的面向,對於golang來講沒有什麼可比性,因為一些作法和注重的部分不一樣。
但大部分情況下,go還是很有競爭力的。
--Changes from C--
Why is the syntax so different from C?
GO認為程式語法應該是簡單,輕量,C語言的語法太多關鍵字、複雜,因此與C語言的語法有大幅不同。
Why are declarations backwards?
將型態宣告放在後面,目的是為了清楚,並一致表示這些宣告的變數都是這個型態。
如C語言,型態的宣告放在前面,變數a、和變數b用逗號隔開放在同一行,兩個變數的型態是不一樣,這樣也不夠清楚。
Why are ++ and – statements and not expressions? And why postfix, not prefix?
(這邊牽扯很多語意邏輯的東西,我不是很清楚)。
大意是說放前面雖然也可以運作得很好,但是放後面是比較傳統的做法,就放後面吧。
Why are there braces but no semicolons? And why can’t I put the opening brace on the next line?
這邊也是compilier的處理,沒有分號在GO裡面不是偷偷插在最後面,而是靠語意分析器斷每一句。
大括號單純存在一行會造成很多問題,因此GO拒絕這麼做。
加上gofmt處理成單一格式,對於語意分析器會好處理很多,就不用另外建立特殊規則去處理一些開放性的格式。
Why do garbage collection? Won’t it be too expensive?
以過去幾年GC技術處理的進步,GO對於GC的記錄有信心,能做到消耗最低的資源消耗以及不會讓系統延遲。
對於並發和多線程,記憶體管理是很重要的課題,尤其在多線程東西的傳遞,要做到安全的釋放是困難的。
(後面不太懂,大意大概是GO認為要做GC這件事)
因為GO幫忙做了GC,所以interface的使用大可不用擔心太多記憶體的問題。
GO語言本身提供的可控制性,遠大於內部GC的有限控制,若有疑問請參考profiling文件。(部分說明不太懂)
Created Date : 2018/08/10
Last Updated Date : 2018/08/10
留言
張貼留言