這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Introducing Go
目錄
- 1Get Started
- 2類型
- 3變數
- 4控制結構
- 5Arrays, Slices, and Maps
- 6Functions
- 7Structs and Interfaces
- 8包
- 9Testing
- 10並發
- 11Next Steps
Get Started
類型
變數
控制結構
- for i<=10 { ... } //for關鍵字這裡用作while
- if:這裡為什麼不加()呢?跟Swift學的?還是跟Python?
Arrays, Slices, and Maps
- x := make(map[string]int) //map的預設值是nil,所有必須先make,才能往裡面add元素
- 嵌套的map(JSON?):elements := map[string]map[string]string { ...
Functions
- 變參://這到底是運行時還是編譯器的?
- func Println(a ...interface{}) (n int, err error)
- xs := []int{1,2,3}; fmt.Println(add(xs...))
- 閉包
- 支援閉包的前提是:外部參考變數是heap上分配的,但Go可以直接返回函數和C語言只能返回函數指標有什麼不同?
- defer, panic, recover
- *與&
Structs and Interfaces
- c := &Circle{0, 0, 5} //這可能是Go語言裡struct的最正常用法?
- 因為參數都是傳值的(?),所以函數一般使用指標來傳參?//C語言不也是傳值的嘛,C++裡可以傳引用&
- func (r *Rectangle) area() float64 { ... }
- ==> r := Rectangle{0, 0, 10, 10}; r.area()
- 表達is-a:嵌入類型(好像另外那個語言也是這種匿名風格的?)
- Interfaces
- type Shape interface { area() float64 }
包
- strings
- strings.Contains("test", "es") //為什麼不是直接在string對象上擴充方法?
- strings.Join([]string{"a","b"}, "-")
- strings.Replace("aaaa", "a", "b", 2) //最後一個參數代表最多替換個數?為什麼不是startIndex呢
- IO:Reader與Writer
- func Copy(dst Writer, src Reader) (written int64, err error)
- bytes.Buffer
- Files and Folders
- file, err := os.Open("test.txt") //rw?
- stat, err := file.Stat() ==> stat.Size()
- os.Open(".").Readdir(-1) //這個代碼有點太低級了
- 使用包path/filepath的目錄遍曆:
- filepath.Walk(".", func(path string, info os.FileInfo, err error) error { ...(可返回filepath.SkipDir停止遍曆) } //似乎沒有控制選項啊?
- container/list://雙鏈表??有沒有進階一點的資料結構
- sort.Sort
- 需要(數組)對象實現3個方法:Len() int、Less(i, j int) bool、Swap(i, j int) //Go語言支援a,b=b,a的交換賦值文法
- hash與密碼學*
- Servers
- TCP
- listener, err := net.Listen("tcp", ":9999")
- for { con, err := listener.Accept() //嗯?必須收到一個串連才能收到下一個嗎?
- err := gob.NewDecoder(c).Decode(&msg) //var msg string; gob是什麼編解碼演算法?
- 用戶端:
- c, err := net.Dial("tcp", "127.0.0.1:9999")
- HTTP
- http.HandleFunc("/hello", hello) //func hello(res http.ResponseWriter, req *http.Request) { ... }
- http.ListenAndServe(":9000", nil)
- 靜態檔案:http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets")),),) //這裡是不是多了幾個逗號?
- RPC(略)
- 解析命令列參數
- flag.Parse()
Testing
- _test.go
- import "testing"
- func TestAverage(t *testing.T) { ...t.Error(...)... }
- $ go test
並發
- <建立channel,並傳遞給goroutine>
- select {
- case <- time.After(time.Second): //逾時
- c := make(chan int, 1) //緩衝的channel是非同步(但是超出限制仍然會阻塞吧)
- 發起http GET請求:res, err := http.Get(url) //這個也太簡潔了吧?(沒有請求Header的設定)
Next Steps
- 閱讀Go pkg下的代碼實現?