Go 語言學習

最近要學習一下分佈式文件系統,瞭解一下分佈式文件系統的容錯機制,就開啓了自學MIT 6.824 Distributed System Spring 2014課程。 java

之前在學校裏面聽過陳康老師講過幾節課,有一些印象,確實很難。原本覺得也是C或者C++實現的,萬萬沒想到的是,居然用高大上的Go語言重寫了分佈式文件系統的框架,python

這讓我等小菜只好膜拜,只好開始學習Go語言。(參考資料:http://golang.org/doc/)golang

  1. 學習記錄

http://tour.golang.org/  一個練習教程,過一遍基本上Go編程有了初步的瞭解。 下一步須要深刻研究GOROUTINE的原理以及應用。編程

1) 變量聲明和初始化 ( 變量聲明 := ,var,以及struct、Arrays、slice、map、channels、mathod、interface)框架

var i, j int = 1, 2
var c, python, java = true, false, "no!" 分佈式

struct:函數

type Vertex struct {
X int
Y int
}oop

Arrays: var a [10]int學習

Slices: p := []int{2, 3, 5, 7, 11, 13}fetch

a := make([]int,5)

var m map[string]Vertex 

m = make(map[string]Vertex]
var m = map[string]Vertex{
"Bell Labs": Vertex{
40.68433, -74.39967,
},
"Google": Vertex{
37.42202, -122.08408,
},
}

函數的聲明  

func swap(x, y string) (string, string)

hypot := func(x, y float64) float64 {
return math.Sqrt(x*x + y*y)
}

Function closures

method 和 interface 自由擴展

type Vertex struct {
X, Y float64
}

func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

Errors

type error interface {

    Error() string

}

Channels

ch := make(chan int)

ch := make(chan int, 100)
Sends to a buffered channel block only when the buffer is full. Receives block when the buffer is empty.
相似於C中的Pipe,用來線程之間傳遞數據

 

2) 基本語法

 GO中沒有while,用for來表示,如for  i < 100 { }

 switch  、 if 、 for 

3) 練習題 

 Exercise: Maps

  1. package main
  2. import (
  3. "code.google.com/p/go-tour/wc"
  4. "strings"
  5. )
  6. func WordCount(s string) map[string]int {
  7. words := strings.Fields(s)
  8. mp := make(map[string]int)
  9. for _,word := range words {
  10. 10. mp[word] += 1
  11. }
  12. return mp
  13. }
  14. func main() {
  15. wc.Test(WordCount)
  16. }

Exercise: Fibonacci closure

  1. func fibonacci() func() int {
  2. a:=0
  3. b:=1
  4. count := 1
  5. res := func() int {
  6. if count==1 {
  7. count++
  8. return 1
  9.  } else {
  10.  c :=a + b
  11.  a = b
  12.  b = c
  13.  return c
  14. }
  15. }
  16. return res
  17. }
  18. func main() {
  19. f := fibonacci()
  20. for i := 0; i < 10; i++ {
  21. fmt.Println(f())
  22. }
  23. }

Advanced Exercise: Complex cube roots

  1. func Cbrt(x complex128) complex128 {
  2. // var z, z1 complex64
  3. z := complex128(1)
  4. z1 := z - ((z*z*z - x) / (3*z*z))
  5. i := 1
  6. for z1!=x && i<10 {
  7. z1 = z1 - ((z1*z1*z1 - x) / (3*z1*z1))
  8. i++;
  9. }
  10. return z1
  11. }
  12. func main() {
  13. fmt.Println(Cbrt(2))
  14. }  (須要把整數強行轉換成complex128,另外也能夠簡單化,直接用real取實數部分)

Exercise: Errors

  1. type ErrNegativeSqrt float64
  2. func (e ErrNegativeSqrt) Error() string {
  3. return fmt.Sprintf("cantnot Sqrt negative number:%v",float64(e))
  4. }
  5. func Sqrt(f float64) (float64, error) {
  6. if f < 0 {
  7. return 0,ErrNegativeSqrt(f); 
  8. }
  9. z := f
  10. for i:=0;i<10;i++ {
  11. z = (z+f/z)/2;
  12. }
  13. return z, nil
  14. }
  15. Exercise: Rot13 Reader
  16. type rot13Reader struct {
  17. r io.Reader
  18. }
  19. func ( rs *rot13Reader) Read(p []byte) (n int, err error) {
  20. n,err = rs.r.Read(p)
  21. for i := 0; i < len(p); i++ {
  22. if (p[i] >= 'A' && p[i] < 'N') || (p[i] >='a' && p[i] < 'n') {
  23. p[i] += 13
  24. } else if (p[i] > 'M' && p[i] <= 'Z') || (p[i] > 'm' && p[i] <= 'z'){
  25. p[i] -= 13
  26. }
  27. }
  28. return 
  29. }
  30. func main() {
  31. s := strings.NewReader(
  32. "Lbh penpxrq gur pbqr!")
  33. r := rot13Reader{s}
  34. io.Copy(os.Stdout, &r)
  35. }

Exercise: Web Crawler

  1. type UrlData struct {
  2. url string
  3. depth int
  4. }
  5. type Fetcher interface {
  6. // Fetch returns the body of URL and
  7. // a slice of URLs found on that page.
  8. Fetch(url string) (body string, urls []string, err error)
  9. }
  10. // Crawl uses fetcher to recursively crawl
  11. // pages starting with url, to a maximum of depth.
  12. func Crawl(url string, depth int, fetcher Fetcher,urldata chan<- *UrlData,quit chan<- int) {
  13. // TODO: Fetch URLs in parallel.
  14. // TODO: Don't fetch the same URL twice.
  15. // This implementation doesn't do either:
  16. defer func() { quit <- 1}()
  17. if depth <= 0 {
  18. return
  19. }
  20. body, urls, err := fetcher.Fetch(url)
  21. if err != nil {
  22. fmt.Println(err)
  23. return
  24. }
  25. fmt.Printf("found: %s %q\n", url, body)
  26. for _, u := range urls {
  27. urldata <- &UrlData{u,depth-1}
  28. }
  29. return
  30. }
  31. func main() {
  32. urldata := make(chan *UrlData)
  33. quit := make(chan int)
  34. url_cache := make(map[string]bool)
  35. // url_cache["http://golang.org/"] = true; 
  36. // go Crawl("http://golang.org/", 4, fetcher,urldata,quit)
  37. go func() { urldata <- &UrlData{"http://golang.org/",4} }() 
  38. Loop:
  39. for i:=0;; {
  40. select {
  41. case <-quit:
  42. i--
  43. if i==0 {
  44. break Loop
  45. }
  46. case url := <- urldata:
  47. if url_cache[url.url] {
  48. break;
  49. }
  50. url_cache[url.url]=true
  51. go Crawl(url.url,url.depth,fetcher,urldata,quit);
  52. i++;
  53. }
  54. }
  55. }

Go語言更加靈活,如聲明更加便捷,能夠直接用短聲明(:=), Switch能夠沒有condition,另外也能夠在case中進行判斷;包含了function value,可以對函數更有效處理;另外函數能夠同時返回多個值,方便處理;包含了interface,並且struct和任意封裝類型均可以擴展方法;除此以外,Go 中包含了function value,Closures,以及很強大的Goroutines,這個太強大了,我瞭解的很少,還須要後續繼續研究。

相關文章
相關標籤/搜索