golang筆記1
- go代碼是用包來組織的,每一個包有一個或多個go文件組成,這些go文件文件放在一個文件夾中
- 每一個源文件開始都用一個package聲明,指明本源文件屬於哪一個包
- pakage聲明後緊跟這導入其餘包
- 導入包以後,是構成源文件的變量、函數、類型生命等
- go語言不須要在語句後家分號
- import時,左括號‘(’要跟import在一行
- 函數的的左花括號'{' 必須跟func關鍵詞在一行
下面這段代碼是一個完整的GO程序golang
package main import( "fmt" ) func main(){ fmt.Println("hello world") }
命令行參數
os包中提供了一些函數與變量與操做系統打交道。os.Args變量中存儲命令行參數。web
os.Args是一個字符串slice變量(字符串數組),能夠直接print該值數組
package main import ( "fmt" "os" ) func main() { fmt.Println(os.Args) fmt.Println(os.Args[1]) }
找出重複行
在輸入中找不重複的行數據結構
// 打印輸入中輸入次數大於1的行 package main import ( "bufio" "fmt" "os" ) func main() { count := make(map[string]int) input := bufio.NewScanner(os.Stdin) for input.Scan() { if(input.Text() == ""){ break } count[input.Text()]++ } for line, num := range count { if num > 1 { fmt.Printf("%d\t%s\n", num, line) } } }
map存儲一個鍵值對組合,提供常量時間的操做來存儲、獲取、測試集合中的元素。鍵是能夠進行相等比較的任意類型,字符串是最多見的鍵類型。值能夠是任意類型。app
map的建立使用make語句函數
count := make(map[string]int)
bufio包能夠有效的處理輸入輸出,bufio.Scanner能夠讀取輸入,以行或者單詞爲間隔。oop
下面這行代碼表示從標準輸入進讀取,每次調用input.Scan()讀取下一行,而且將結尾的換行去掉;調用input.Text()獲取讀到的內容。測試
input := bufio.NewScanner(os.Stdin) for input.Scan(){ fmt.Println(input.Text()) }
除了從標準輸入中處理,更爲普遍的是從文件中的輸入內容中處理,下面代碼實現了從文件中讀取動畫
// 打印輸入中輸入次數大於1的行 package main import ( "bufio" "fmt" "os" ) func main() { count := make(map[string]int) files := os.Args[1:] if len(files) == 0 { countLines(os.Stdin, count) } else { for _, arg := range files { f, err := os.Open(arg) if err != nil { fmt.Fprintf(os.Stderr, "dup err: %v\n", err) continue } countLines(f, count) f.Close() } } for line, num := range count { if num > 1 { fmt.Printf("%d\t%s\n", num, line) } } } func countLines(f *os.File, count map[string]int) { input := bufio.NewScanner(f) for input.Scan() { if input.Text() == "" { break } count[input.Text()]++ } }
首先在命令行參數中讀取文件名,而後用os.Open()打開,此處返回的值是(f, err),f 的類型是*os.File的指針類型。這裏跟c語言中的標準流同樣。spa
// files是輸入文件名數組 _, files := os.Args[1:] // 對每個輸入的文件進行讀取, arg是每一個文件的名字 // f是文件指針 for _,arg := files { f, err := os.Open(arg) countLines(f, count) f.Close() }
還須要注意的是,map是對make建立的數據結構的引用。** 當一個map被傳遞給一個函數時,函數接收到這個引用的副本,全部調用函數對map改變時,調用者使用的map也會產生改變。**這相似與C語言中的指針調用。
上面讀取文件的方式是「流」的模式讀取,用法與c語言中的文件流相似。原理上來講,能夠用這種方式處理大量數據。
一個可選方式是一次讀取一整塊數據到大塊內存,一次性的分割全部行,後面使用這種方式處理該問題。
// 打印輸入中輸入次數大於1的行 package main import ( "bufio" "fmt" "io/ioutil" "os" "strings" ) func main() { count := make(map[string]int) files := os.Args[1:] if len(files) == 0 { countLines(os.Stdin, count) } else { for _, arg := range files { data, err := ioutil.ReadFile(arg) if err != nil { fmt.Fprintf(os.Stderr, "dup err: %v\n", err) continue } for _, line := range strings.Split(string(data), "\n") { count[line]++ } } } for line, n := range count { if n > 1 { fmt.Printf("%d\t%s\n", n, line) } } } func countLines(f *os.File, count map[string]int) { input := bufio.NewScanner(f) for input.Scan() { if input.Text() == "" { break } count[input.Text()]++ } }
這裏是一次將所有的文件數據讀入,而後根據"\n"將數據分割爲行。
//讀取文件內容到data data,err := ioutil.ReadFile(file) //按行分割 strings.Split(string(data), "\n")
GIF動畫
package main import ( "image" "image/color" "image/gif" "io" "log" "math" "math/rand" "net/http" "os" "time" ) var palette = []color.Color{color.White, color.Black} const ( whiteIndex = 0 blackIndex = 1 ) func main() { rand.Seed(time.Now().UTC().UnixNano()) if len(os.Args) > 1 && os.Args[1] == "web" { handler := func(w http.ResponseWriter, r *http.Request) { lisajous(w) } http.HandleFunc("/", handler) log.Fatal(http.ListenAndServe("localhost:8000", nil)) return } lisajous(os.Stdout) } func lisajous(out io.Writer) { const ( cycles = 5 res = 0.001 size = 100 nframes = 64 delay = 8 ) freq := rand.Float64() * 3.0 anim := gif.GIF{LoopCount: nframes} phase := 0.0 for i := 0; i < nframes; i++ { rect := image.Rect(0, 0, 2*size+1, 2*size+1) img := image.NewPaletted(rect, palette) for t := 0.0; t < cycles*2*math.Pi; t += res { x := math.Sin(t) y := math.Sin(t*freq + phase) img.SetColorIndex(size+int(x*size+0.5), size+int(y*size+0.5), blackIndex) } phase += 0.1 anim.Delay = append(anim.Delay, delay) anim.Image = append(anim.Image, img) } gif.EncodeAll(out, &anim) }