學習路徑:
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())
複製程式碼