go學習筆記劃重點

全面攻城發表於2018-01-18

學習路徑:

https://github.com/chai2010/advanced-go-programming-book

https://github.com/astaxie/build-web-application-with-golang

重點一

1 定義三個變數,它們分別初始化為相應的值
	vname1為v1,vname2為v2,vname3為v3
	編譯器會根據初始化的值自動推匯出相應的型別
2 vname1, vname2, vname3 := v1, v2, v3
3 現在是不是看上去非常簡潔了?:=這個符號直接取代了var和type,這種形式叫做簡短宣告。不過它有一個限制,那就是它只能用在函式內部;在函式外部使用則會無法編譯通過,所以一般用var方式來定義全域性變數。
複製程式碼

重點二

_(下劃線)是個特殊的變數名,任何賦予它的值都會被丟棄。在這個例子中,我們將值35賦予b,並同時丟棄34:
_, b := 34, 35

複製程式碼

重點三

Go裡面有一個關鍵字iota,這個關鍵字用來宣告enum的時候採用,它預設開始值是0,const中每增加一行加1:

package main
import (
  "fmt"
)
const (
  x = iota // x == 0
  y = iota // y == 1
  z = iota // z == 2
  w        // 常量宣告省略值時,預設和之前一個值的字面相同。這裡隱式地說w = iota,因此w == 3。其實上面y和z可同樣不用"= iota"
)
const v = iota // 每遇到一個const關鍵字,iota就會重置,此時v == 0
const (
  h, i, j = iota, iota, iota //h=0,i=0,j=0 iota在同一行值相同
)
const (
  a       = iota //a=0
  b       = "B"
  c       = iota             //c=2
  d, e, f = iota, iota, iota //d=3,e=3,f=3
  g       = iota             //g = 4
)
func main() {
  fmt.Println(a, b, c, d, e, f, g, h, i, j, x, y, z, w, v)
}


複製程式碼

重點四

Go之所以會那麼簡潔,是因為它有一些預設的行為:
  • 大寫字母開頭的變數是可匯出的,也就是其它包可以讀取的,是公有變數;小寫字母開頭的就是不可匯出的,是私有變數。
  • 大寫字母開頭的函式也是一樣,相當於class中的帶public關鍵詞的公有函式;小寫字母開頭的就是有private關鍵詞的私有函式。

複製程式碼

重點五

連結

重點六

Go有goto語句——請明智地使用它。用goto跳轉到必須在當前函式內定義的標籤。例如假設這樣一個迴圈:
func myFunc() {
  i := 0
Here:   //這行的第一個詞,以冒號結束作為標籤
  println(i)
  i++
  goto Here   //跳轉到Here去
}

複製程式碼

重點七

For 可以配合while 使用  
Sum  := 1 
For sum< 1000 {
	Sum += sum
} 
for配合range可以用於讀取slice和map的資料:
for k,v:=range map {
	fmt.Println("map's key:",k)
	fmt.Println("map's val:",v)
}
複製程式碼

重點八

連結

重點九

傳指標比較輕量級 (8bytes),只是傳記憶體地址,我們可以用指標傳遞體積大的結構體。如果用引數值傳遞的話, 在每次copy上面就會花費相對較多的系統開銷(記憶體和時間)。所以當你要傳遞大的結構體的時候,用指標是一個明智的選擇。
Go語言中channel,slice,map這三種型別的實現機制類似指標,所以可以直接傳遞,而不用取地址後傳遞指標。(注:若函式需改變slice的長度,則仍需要取地址傳遞指標)

複製程式碼

重點十

連結

重點十一

Go語言實現了反射,所謂反射就是能檢查程式在執行時的狀態。我們一般用到的包是reflect包。如何運用reflect包,官方的這篇文章詳細的講解了reflect包的實現原理,laws of reflection
使用reflect一般分成三步,下面簡要的講解一下:要去反射是一個型別的值(這些值都實現了空interface),首先需要把它轉化成reflect物件(reflect.Type或者reflect.Value,根據不同的情況呼叫不同的函式)。這兩種獲取方式如下:
t := reflect.TypeOf(i)    //得到型別的後設資料,通過t我們能獲取型別定義裡面的所有元素
v := reflect.ValueOf(i)   //得到實際的值,通過v我們獲取儲存在裡面的值,還可以去改變值
轉化為reflect物件之後我們就可以進行一些操作了,也就是將reflect物件轉化成相應的值,例如
tag := t.Elem().Field(0).Tag  //獲取定義在struct裡面的標籤
name := v.Elem().Field(0).String()  //獲取儲存在第一個欄位裡面的值
獲取反射值能返回相應的型別和數值
var x float64 = 3.4
v := reflect.ValueOf(x)
fmt.Println("type:", v.Type())
fmt.Println("kind is float64:", v.Kind() == reflect.Float64)
fmt.Println("value:", v.Float())

複製程式碼

重點十二

連結

相關文章