//函数名TestXXX(t *testing.T)固定写法 funcTestTriangle(t *testing.T) { //参数化测试 tests := []struct{ a, b, c int }{ {3, 4, 5}, {5, 12, 13}, {8, 15, 17}, {12, 35, 37}, {30000, 40000, 50000}, }
for _, tt := range tests { if actual := calcTriangle(tt.a, tt.b); actual != tt.c { t.Errorf("calcTriangle(%d, %d); " + "got %d; expected %d", tt.a, tt.b, actual, tt.c) } } }
分支
funcgrade(score int)string { g := "" switch { case score < 0 || score > 100: panic(fmt.Sprintf("Wrong score: %d", score)) case score < 60: g = "F" case score < 80: g = "C" case score < 90: g = "B" case score <= 100: g = "A" } return g }
循环
funcforever() { //死循环 for { fmt.Println("abc") } }
funcconvertToBin(n int)string { result := "" //三分号循环 for ; n > 0; n /= 2 { lsb := n % 2 result = strconv.Itoa(lsb) + result } return result }
//无需第三个变量交换两个变量的值 funcswap(a, b int)(int, int) { return b, a }
//可变参数 funcsum(numbers ...int)int { s := 0 for i := range numbers { s += numbers[i] } return s }
//多个返回值 funcdiv(a, b int)(q, r int) { return a / b, a % b }
//函数式参数 funcapply(op func(int, int)int, a, bint) int { p := reflect.ValueOf(op).Pointer() opName := runtime.FuncForPC(p).Name() fmt.Printf("Calling function %s with args "+ "(%d, %d)\n", opName, a, b) return op(a, b) }
//pop fmt.Println("Popping from front") front := s2[0] s2 = s2[1:]
fmt.Println("Popping from back") tail := s2[len(s2)-1] s2 = s2[:len(s2)-1]
字符串操作
s := "Yes我爱中国!"// UTF-8 fmt.Println(s) //Yes我爱中国!
for _, b := range []byte(s) { fmt.Printf("%X ", b)//十六进制 } fmt.Println() //59 65 73 E6 88 91 E7 88 B1 E4 B8 AD E5 9B BD 21
for i, ch := range s { // ch is a rune fmt.Printf("(%d %X) ", i, ch) } fmt.Println() //(0 59) (1 65) (2 73) (3 6211) (6 7231) (9 4E2D) (12 56FD) (15 21)
funcmain() { for i := 0; i < 1000; i++ { gofunc(i int) { for { fmt.Printf("Hello from "+ "goroutine %d\n", i) } }(i) } time.Sleep(time.Minute)
recover
package main
import ( "fmt" )
functryRecover() { deferfunc() { r := recover() if r == nil { fmt.Println("Nothing to recover. " + "Please try uncomment errors " + "below.") return } if err, ok := r.(error); ok { fmt.Println("Error occurred:", err) } else { panic(fmt.Sprintf("I don't know what to do: %v", r)) } }()
// Uncomment each block to see different panic // scenarios.
// Normal error //panic(errors.New("this is an error"))
// Division by zero //b := 0 //a := 5 / b //fmt.Println(a)
// Causes re-panic //panic(123) }
funcmain() { tryRecover() }
http
funcmain() { request, err := http.NewRequest(http.MethodGet, "http://www.imooc.com", nil) request.Header.Add("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1")
funcdoWork(id int, w worker) { for n := range w.in { fmt.Printf("Worker %d received %c\n", id, n) w.done() } }
type worker struct { in chanint done func() }
funccreateWorker(id int, wg *sync.WaitGroup)worker { w := worker{ in: make(chanint), done: func() { wg.Done() }, } go doWork(id, w) return w }
funcchanDemo() { var wg sync.WaitGroup
var workers [10]worker for i := 0; i < 10; i++ { workers[i] = createWorker(i, &wg) }
wg.Add(20) for i, worker := range workers { worker.in <- 'a' + i } for i, worker := range workers { worker.in <- 'A' + i }
wg.Wait() }
funcmain() { chanDemo() }
package main
import ( "fmt" "time" )
funcworker(id int, c chanint) { for n := range c { fmt.Printf("Worker %d received %c\n", id, n) } }
funccreateWorker(id int)chan<- int { c := make(chanint) go worker(id, c) return c }
funcchanDemo() { var channels [10]chan<- int for i := 0; i < 10; i++ { channels[i] = createWorker(i) }
for i := 0; i < 10; i++ { channels[i] <- 'a' + i }
for i := 0; i < 10; i++ { channels[i] <- 'A' + i }
time.Sleep(time.Millisecond) }
funcbufferedChannel() { c := make(chanint, 3) go worker(0, c) c <- 'a' c <- 'b' c <- 'c' c <- 'd' time.Sleep(time.Millisecond) }
funcchannelClose() { c := make(chanint) go worker(0, c) c <- 'a' c <- 'b' c <- 'c' c <- 'd' close(c) time.Sleep(time.Millisecond) }
funcmain() { fmt.Println("Channel as first-class citizen") chanDemo() fmt.Println("Buffered channel") bufferedChannel() fmt.Println("Channel close and range") channelClose() }
select
package main
import ( "fmt" "math/rand" "time" )
funcgenerator()chanint { out := make(chanint) gofunc() { i := 0 for { time.Sleep( time.Duration(rand.Intn(1500)) * time.Millisecond) out <- i i++ } }() return out }
funcworker(id int, c chanint) { for n := range c { time.Sleep(time.Second) fmt.Printf("Worker %d received %d\n", id, n) } }
funccreateWorker(id int)chan<- int { c := make(chanint) go worker(id, c) return c }
funcmain() { var c1, c2 = generator(), generator() var worker = createWorker(0)
var values []int tm := time.After(10 * time.Second) tick := time.Tick(time.Second) for { var activeWorker chan<- int var activeValue int iflen(values) > 0 { activeWorker = worker activeValue = values[0] }
select { case n := <-c1: values = append(values, n) case n := <-c2: values = append(values, n) case activeWorker <- activeValue: values = values[1:]
case <-time.After(800 * time.Millisecond): fmt.Println("timeout") case <-tick: fmt.Println( "queue len =", len(values)) case <-tm: fmt.Println("bye") return } } }