<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] # 1.2 Go 語言綜述 Go 語言的設計哲學是簡潔,在 Go 團隊的一次訪談中,Rob Pike 和 Ken Thompson 均有提到 Go 在誕生之初就選擇了一條與以往的編程語言所選擇的不同方法,僅嘗試提供編程過程中的必需品, 剔除掉紛繁復雜的語法糖和日漸增多的特性列表,在進入本書內容之前,我們先對這一語言做一次 相對完整的回顧。 ## 1.1.1 基礎類型與值 ### 基本類型 原始的數值類型包括: ``` bool, uint, uint8, uint16, uint32, uint64, int, int8, int16, int32, int64, float32, float64 ``` ### 常量 const 與變量 var 常量`const`與變量`var`是編程語言里司空見慣的概念,Go 語言也不例外。 常量與變量的聲明允許類型推導,也允許明確指定值的類型。 ``` const ( name = "val" PI float64 = 3.1415926 ) var ( age = 18 ) ``` 變量除了使用`var`來進行聲明外,還可以在函數內部通過`:=`進行聲明。 ## 1.1.2 程序的基本單元 Go 語言本身只有 25 個關鍵字,涵蓋了包管理、常量與變量、流程控制、函數調用、數據結構 和并發控制六個方面的語言特性。 ### 包 package import Go 語言以包為代碼組織的最小單位,不允許產生包與包之間的循環依賴。 包管理涉及兩個關鍵字,`package`負責聲明當前代碼所在的包的包名,`import`則負責導入 當前包所依賴的包。導入的形式包括絕對路徑和相對路徑,還能夠在導入時候對包指定別名,甚至將別名指定為下劃線,只導入所依賴包的`init`初始化函數。 ``` package foo import ( "go/types" "golang.org/x/syscall" "errors" xerrors "golang.org/x/errors" _ "os/signal" ) ``` 特殊的,main 包只允許出現一次。 ### 函數 #### 函數的聲明 ``` func return func foo(argc int, argv []string) float64 { ... return 0 } ``` 內建的打印函數 ~~~ func print(args ...T) func println(args ...T) ~~~ #### 延遲函數 defer #### 主函數 #### 初始化函數 ### 控制流 #### 條件控制 ``` if else break continue switch case default fallthrough ``` #### 循環控制 ``` for range ``` #### 跳躍 ``` goto ``` ## 1.1.3 數據容器與高級類型 ### 字符串 ``` `string` ``` ### 切片與數組 ``` [10]byte // 數組 []byte // 切片 ``` 支持切片的基本操作 ~~~ // 往切片末尾追加元素 func append(slice []T, elems ...T) []T // 將 src 拷貝到 dst func copy(dst, src []T) int ~~~ 除了使用類型聲明外,還可以使用 make 和 new 來創建一個數據容器: ~~~ func make(t T, size ...IntegerT) T func new(T) *T ~~~ 內建 len 和 cap ~~~ func len(v T) int func cap(v T) int ~~~ ### 散列表 關鍵字 map 用于聲明一個散列表類型 map\[K\]V。 支持散列表操作的內建 ~~~ func delete(m map[T]U, key T) ~~~ 除此之外,make/new/len 也是可以用的 ### 結構體 ~~~ type struct interface ~~~ ### 接口 ### 類型別名 語言自身的類型別名包括: const ( true = 0 == 0 false = 0 != 0 iota = 0 ) 別名類型包括:byte rune 還可以使用 type 關鍵字來定義類型別名: ~~~ type New Old ~~~ ### 指針與零值 ~~~ var nil T ~~~ ~~~ uintptr ~~~ ## 1.1.4 并發與同步原語 ### `go`塊 關鍵字 go 用于創建基本的并發單元。 ``` go func() { // 并發代碼塊 ... }() ``` 被并發的函數將發生在一個獨立的 Goroutine 中,與產生 Goroutine 的代碼并發的被執行。 ### Channel Channel 主要有兩種形式: 1. **有緩存 Channel(buffered channel)**,使用`make(chan T, n)`創建 2. **無緩存 Channel(unbuffered channel)**,使用`make(chan T)`創建 其中`T`為 Channel 傳遞數據的類型,`n`為緩存的大小,這兩種 Channel 的讀寫操作都非常簡單: ``` // 創建有緩存 Channel ch := make(chan interface{}, 10) // 創建無緩存 Channel ch := make(chan struct{}) // 發送 ch &lt;- v // 接受 v := &lt;- ch ``` 他們之間的本質區別在于其內存模型的差異,這種內存模型在 Channel 上體現為: * 有緩存 Channel:`ch <- v`發生在`v <- ch`之前 * 有緩存 Channel:`close(ch)`發生在`v <- ch && v == isZero(v)`之前 * 無緩存 Channel:`v <- ch`發生在`ch <- v`之前 * 無緩存 Channel: 如果`len(ch) == C`,則從 Channel 中收到第 k 個值發生在 k+C 個值得發送完成之前 直觀上我們很好理解他們之間的差異: 對于有緩存 Channel 而言,內部有一個緩沖隊列,數據會優先進入緩沖隊列,而后才被消費, 即向通道發送數據`ch <- v`發生在從通道接受數據`v <- ch`之前; 對于無緩存 Channel 而言,內部沒有緩沖隊列,即向通道發送數據`ch <- v`一旦出現, 通道接受數據`v <- ch`會立即執行, 因此從通道接受數據`v <- ch`發生在向通道發送數據`ch <- v`之前。 我們隨后再根據實際實現來深入理解這一內存模型。 Go 語言還內建了`close()`函數來關閉一個 Channel: ``` close(ch) ``` 但語言規范規定了一些要求: * 關閉一個已關閉的 Channel 會導致 panic * 向已經關閉的 Channel 發送數據會導致 panic * 向已經關閉的 Channel 讀取數據不會導致 panic,但讀取的值為 Channel 緩存數據的零值,可以通過接受語句第二個返回值來檢查 Channel 是否關閉: ``` v, ok := &lt;- ch if !ok { ... // Channel 已經關閉 } ``` ### Select Select 語句伴隨 Channel 一起出現,常見的用法是: ``` select { case ch &lt;- v: ... default: ... } ``` 或者: ``` select { case v := &lt;- ch: ... default: ... } ``` 用于處理多個不同類型的`v`的發送與接收,并提供默認處理方式。 ## 1.1.5 錯誤處理 Go 語言的錯誤處理被設計為值類型,錯誤以接口的形式在語言中進行表達: ``` type error interface { Error() string } ``` 任何實現了`error`接口的類型均可以作為`error`類型。對于下面的`CustomErr`結構而言: ``` type CustomErr struct { err error } func (c CustomErr) Error() string { return fmt.Sprintf("err: %v", c.err) } ``` 由于其實現了`Error()`方法,于是可以以`error`類型返回給上層調用: ``` func foo() error { return CustomErr{errors.New("this is an error")} } func main() { err := foo() if err != nil { panic(err) } } ``` 除了錯誤值以外,還可以使用`panic`與`recover`內建函數來進行錯誤的傳播: ``` func panic(v interface{}) func recover() interface{} ``` ## 1.1.6 基礎工具 工具并不屬于語言本身,相反它卻在 Go 語言中有著舉足輕重的地位。 ### go fmt ### go vet ### go mod ## 1.1.7 小結 我們使用了不算多的篇幅,基本上介紹完了整個 Go 語言的核心及使其成功運行的必備工具, 雖然有諸如 complex64、complex128 基礎類型和 complex、real、imag 等內建函數沒有 在這里進行介紹,但他們在除了科學計算等領域外極為少見,讀者在熟悉語言的其他部分后, 對這些為數不多的特性的掌握甚至都不是一個時間問題。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看