入門筆記 --- Golang 語法注意事項(一)

1. import 寫法

  • 導入標準庫或其餘模塊golang

    • 導入標準庫,直接寫庫的名稱便可正則表達式

    • 導入其餘模塊可使用相對路徑或絕對路徑數組

      import (
         "fmt"  // 庫的名稱
         "./modal" // 絕對路徑
         "my/modal" // 相對路徑(GOPATH/src/my/modal)  
      )
      複製代碼
  • 特殊的導入包的使用方法bash

    • 點操做
      使用點操做導入的包你能夠直接使用包內的函數而省略包名如fmt.Print()能夠寫成Print()閉包

    • 別名操做函數

      當你導入的包名稱比較難記憶或者有命名衝突的時候,你可使用別名操做能夠把包命名成一個另一個不會衝突且容易記憶的名稱ui

    • _ 操做 該操做只是引入一個包。當它導入一個包時,包全部的init()函數都會執行,可是咱們沒法經過包名等來調用包內的導出函數(咱們有時候只須要包的init()函數而不須要其餘函數) 因此,該操做的做用只是用來調用包的init() 函數編碼

      import (
          . "fmt" // 點操做
          f "fmt" // 別名操做
          _ "my/modal" // _ 操做
      )
      複製代碼
  • import 導入包的過程 程序的初始化和執行都從main包開始,若是,mian包還導入了其餘的包,那麼在main包中,會先導入其餘的包(其他包也同樣),而後再將包的全局常量和變量進行初始化,接着在執行init()函數,最後在執行main函數。在導入的其他包中,重複導入包、初始化常量、變量、執行init操做。 spa

2.雙引號、單引號、反引號 & byte與rune區別

  • 雙引號表示字符串string,其實質是一個byte類型的數組,Go語言的字符串的字節使用UTF-8編碼標識Unicode文本。它建立的字符串是可解析、可轉義的字符串字面量,可是它不支持多行.指針

    golang中string底層是經過byte數組實現的。中文字符在unicode下佔2個字節,在utf-8編碼下佔3個字節,而golang默認編碼正好是utf-8。因此, str="abc 中文" 長度爲10

  • 單引號表示rune類型,該類型是int32的別名,功能與int32相差無幾。它建立的是碼點字面量,是不作任何轉義的原始內容.

    它與byte類型相似,都用來表示字符類型的變量,可是

    • byte 等同於int8,經常使用來處理ascii字符
    • rune 等同於int32,經常使用來處理unicode或utf-8字符

    因此在使用rune類型將str = "abc 中文" 轉化類型,即 len([]rune(str))的值爲6

  • 反引號是用來建立字符串,可是它建立的是原生的字符串字面量(與雙引號表示的string不一樣),它能夠由多行組成,可是不支持任何轉義序列,原生的字符串字面量多用於書寫多行消息、HTML以及正則表達式。

3.變量聲明後默認值

  • 數字類型(包括整型、浮點型:int八、byte、int1六、uint、uintprt、float3二、float64):默認值爲0。
  • 布爾類型(bool):默認值爲false。
  • 複數類型(complex6四、complex128):默認值爲0+0i。
  • 字符串(string):默認值爲」「。
  • 錯誤類型(error):默認值爲nil。
  • 派生類型:其中如:指針、切片、字典、通道、接口等:默認值爲nil。而數組的默認值要根據其數據類型來肯定。例如:var a [4]int,其默認值爲[0 0 0 0]。

4.錯誤捕獲&異常處理機制

  • 其餘語言處理機制 在Java、JavaScript、PHP等語言中,異常處理是依靠try...catch、throw來處理。

    try{
       // 可能發生異常的語句
    }catch(e){
       // 捕獲到錯誤e,中止執行上面的語句,跳轉到這個代碼塊
    }finally{
       // 不管上述代碼塊怎麼執行,這部分代碼都確定執行
    }
    
    throw Error("") // 拋出錯誤,可被try...catch捕獲
    複製代碼
  • go錯誤處理機制 在go中,依靠panic、recover函數來處理,它們的做用分別與throw和catch語句類似,固然也存在不一樣之處。

  • panic函數

    func panic(interface{})//接受任意類型參數 無返回值 複製代碼
    • panic能夠將原有的控制流程中斷,進入到一個"恐慌"流程。這種恐慌流程能夠顯式調用panic()函數產生或者由運行時錯誤產生(例如訪問越界的數組下標)。
    • panic會在調用它的函數中向本層和它的全部上層逐級拋出,若一直沒有recover將其捕獲,程序退出後會產生crash。
    • panic並不會影響defer的函數的執行。
    • 與其餘語言throw相識,會拋出異常。
  • recover函數

    func recover() interface{}//能夠返回任意類型 無參數
    複製代碼
    • 它是一個內建函數,可使進入使人恐慌的進行中的goroutime恢復(即捕獲panic拋出的異常)。
    • 在正常的執行過程當中,調用recover會返回nil,而且沒有其它任何效果。
    • 功能與其餘語言的catch類似,能夠捕獲異常。
    • 通常狀況下,recover()應該在一個使用defer關鍵字的函數中執行以有效截取錯誤處理流程。若是沒有在發生異常的goroutine中明確調用恢復
  • defer函數

    • 它是go的延遲執行語句,它會延遲執行一個函數,在他所屬的那個函數的return將結果寫入返回值後,才執行被延遲的函數

    • defer執行順序

      * 執行到return語句->
          * return給返回值賦值->
          * 執行的defer延遲的函數->
          * 函數攜帶返回值返回
      複製代碼
    • 多個defer的執行順序爲LIFO(後進先出),全部的的份兒保存在一個延遲調用棧

    • defer修飾的函數值和參數取值都會在defer語句執行時保存,等到上一級函數返回時,按LIFO執行defer函數

      若是函數的參數爲指針,則須要注意函數執行時,參數是否修改,由於defer執行時,保存的也是參數的指針

    • defer函數的任何返回都會被丟棄

    • 若是一個defer的函數值爲nil,則這個defer函數會在函數執行時panic(異常),而不是在defer語句執行時。

    • 若是defer修飾的是一個含有閉包的函數(同時你也想讓閉包函數執行)

    • 那麼你須要定義一個變量,將函數返回的閉包複製給這個變量後再修飾這個變量

      func test(){
           return func(){}
      }
      test1 := test()
      defer test1
      複製代碼
    • 或者你直接在修飾的後面再加個()表明返回的閉包當即執行

      defer test()()
      複製代碼
相關文章
相關標籤/搜索