Golang學習筆記:常見問題

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

Golang學習筆記:常見問題

標籤(空格分隔): golang

參考GolangFrequently Asked Questions ,很好的參考文檔,理解Golang必讀。

1. Golang的特點和發起目的

Golang的特點以及要解決的問題概括起來就是三點:
1. concurrent : 多核 解決方式-> 語言層級並發, goroutine
2. garbage-collected language : c/c++的不足
3. fast compilation : c/c++等的不足, 依賴簡單,類型系統簡單,非傳統OO。開發更簡單快捷。
這種簡單設計的特點很容易讓人和C++對比,對比C++就是砍了90%特性,減少90%的麻煩。更好的對比可能是C,better c with goroutine and garbage-collection。

2. Golang設計原則

  1. felicity of programming : 儘可能的簡化代碼編寫規則,這點在各種解釋語言,c++11等裡面都可以體現一部分了,在golang上的體現就是如包的定義,編譯安裝,沒有標頭檔,no forward declarations,:= 類型推斷等等
  2. orthogonality of concepts : 另一個原則是概念設計儘可能正交orthogonal,這樣理解使用會更簡單。 Methods can be implemented for any type; structures represent data while interfaces represent abstraction; and so on. Orthogonality makes it easier to understand what happens when things combine.當然一旦設計正交,需要的概念也變得很少。
  3. speed of compilation

3. 為什麼沒有泛型

Generics may well be added at some point. We don’t feel an urgency for them。為什麼需要泛型可以參考這篇文章,但是泛型可以帶來好處也會增加複雜度,golang可能以後會添加泛型支援,目前是一個open issue。

4. 為什麼沒有exceptions

這點是golang遭受使用者(尤其是c++,java使用者)詬病的重要原因,實際上Golang提供了panic,recover文法類似try catch。但是個人理解為什麼沒有只是一個選擇問題,而不是技術問題。在很多語言的編碼風格裡尤其是Objective-C,一般都是使用Error Object來傳遞錯誤,雖然現在try catch的效能損失可以忽略不計,但是try catch的壞處是容易濫用,導致使用者忽略error和exception的區別,另外Golang提供的多傳回值也方便了error傳遞這種風格的使用,我個人對這種設計並不反感。

5. 為什麼沒有assertion

和沒有exceptions有點類似: programmers use them as a crutch to avoid thinking about proper error handling and reporting,當然這種牽強的說法作者自己也有點沒底氣:We understand that this is a point of contention. There are many things in the Go language and libraries that differ from modern practices, simply because we feel it’s sometimes worth trying a different approach。

6. 為什麼build concurrency on the ideas of CSP

(Communicating Sequential Processes)
一是Erlang,Occam 等的經驗,二是便於語言層面構建。

7. Why goroutines instead of threads

把線程式控制制的複雜度從使用者空間轉移到語言層面(使用者層面不需要關係協程還是線程,讓並發的使用簡單和高效是其設計目的)。The Go scheduler

8. 為什麼map非安全執行緒

知道map非安全執行緒就行了,這種設計大都是一個trade off

9. Golang是面對對象語言嗎

這個問題不太對,面對對象更多的是一種設計,而非語言特性,只是不同語言的實現和支援有所不同。在Golang裡面的方式是interface,無type hierarchy, subclass的方式有點類似C,比C++等更general。同時Golang裡面的Method也更general,可以給任何類型添加方法,總的來說的就是輕量級,更簡單卻能做更多事。個人覺得是Golang裡最美的設計,面試官再問你會不會面對對象編程,你就打他臉。

10. 為什麼Golang沒有運算子或者方法重載

沒什麼好說的,運算子和方法重載沒什麼用。即使在提供這類功能的語言裡面也不要使用(除非一些極端場合如資料處理架構重載+*符號用於運算矩陣,這個場合非常少,更多時候這種功能大概會帶來1%的便利和1000%的代碼混亂和可讀性降低)。

11. interface的一個有疑問的例子Why doesn’t type T satisfy the Equal interface

type Equaler interface {    Equal(Equaler) bool}type T intfunc (t T) Equal(u T) bool { return t == u } // does not satisfy Equaler

因為Equaler的Equal函數需要的類型不同,正確的實現方式為

type T2 intfunc (t T2) Equal(u Equaler) bool { return t == u.(T2) }  // satisfies Equaler另一個例子type Opener interface {   Open() Reader}func (t T3) Open() *os.File//T3 does not satisfy Opener, although it might in another language.

Golang沒有自動類型轉換,也沒有多態(類之間),這也是作者的trade off

12. Error和nil的一個例子

func returnsError() error {    var p *MyError = nil    if bad() {        p = ErrBad    }    return p // Will always return a non-nil error.}

這和interface的實現有關:

Under the covers, interfaces are implemented as two elements, a type and a value. The value, called the interface’s dynamic value, is an arbitrary concrete value and the type is that of the value. For the int value 3, an interface value contains, schematically, (int, 3).
An interface value is nil only if the inner value and type are both unset, (nil, nil). In particular, a nil interface will always hold a nil type. If we store a nil pointer of type *int inside an interface value, the inner type will be *int regardless of the value of the pointer: (*int, nil). Such an interface value will therefore be non-nil even when the pointer inside is nil.

一個更直觀點的例子type myError struct{}func (this *myError) Error() string { return "" }var error1 *myError = nilvar error2 error = error1// to interface => error2 != nil

13. go不支援tagged or untagged union

untagged union不安全,tagged union或者Variant types, algebraic type則和interface有重合

14. 為什麼沒有隱式類型轉換

作者認為這種功能帶來的隱患比便利要多,Golang中Int和int64都不是一個類型,不能隱式轉換。

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

知道這回事就行了slices的實現方式是對底層array的引用(見), 參考

理解了再看這個例子就明白了sa := make([]int, 10)fmt.Println("sa:", saa)//saa: [0 0 0 0 0 0 0 0 0 0]sb := saa[1:8]sb[2] = 2sb = append(sbb, 8) //sa 也被修改了fmt.Println("sa:", sa, "sb:", sb)// saa: [0 0 0 2 0 0 0 0 8 0] sbb: [0 0 2 0 0 0 0 8]

16. When should I use a pointer to an interface

Almost never.傳一個指標指向interface大都數時候都是錯誤。另:The insight is that although a pointer to a concrete type can satisfy an interface, with one exception a pointer to an interface can never satisfy an interface.

17. 關於閉包的一個例子

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    }}// 輸出是c c c 因為v共用一個變數 而輸出取決於fmt.Println調用的時候v儲存的數值    // 正確的寫法為    for _, v := range values {        go func(u string) {            fmt.Println(u)            done <- true        }(v)    }    // 或者做一個本地拷貝    for _, v := range values {        v := v // create a new 'v'. 注意位置 寫在func裡面還是不對        go func() {            fmt.Println(v)            done <- true        }()    }

18. 沒有?:操作符

差評

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.