for scanner.Scan() { fmt.Println(scanner.Text()) } }
一个小总结
go语言的变量定义,变量名在前,类型在后
导入的包一定要使用
定义的变量一定要使用,如果不想使用可以用_来代替
4. 函数
返回值类型写在后面
可返回多个值
函数作为参数实现函数式编程
没有默认值,可变参数列表
4.1 函数的定义
标准的函数
1 2 3 4
//多个返回值 funcprint(a int){ fmt.Println(a) }
多个返回值
1 2 3 4 5
//多个返回值 funcdiv(a, b int) (q, r int) { i, _ := eval(a, b, "/") return i, a % b }
4.2 函数式编程
1 2 3 4 5 6 7
funcapply(op func(float64, float64)float64, a, b float64) float64 { //通过反射来 p := reflect.ValueOf(op).Pointer() opName := runtime.FuncForPC(p).Name() fmt.Println("Calling function is %s with args (%d,%d)", opName, a, b) return op(a, b) }
4.3 可变参数列表
1 2 3 4 5 6 7 8
funcsum(nums ...int)int { sum := 0 for i := range nums { sum = sum + nums[i] fmt.Println(i) } return sum }
funcnorepeateSubstr(s string)int { start := 0 m := make(map[string]int) max := 0 for i, ch := range []byte(s) { if v, hasKey := m[string(ch)]; hasKey && v >= start { start = m[string(ch)] + 1 } //当前最大值减去起始值,比较大小 if i-start+1 > max { max = i - start + 1 } m[string(ch)] = i } return max }
funcwork(id int, c chanint) { for { fmt.Printf("work %d,do %c\n", id, <-c) } } funcchanDemo() { var channels [10]chanint
for i := 0; i < 10; i++ { channels[i] = make(chanint) go work(i, channels[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) } funcmain() { chanDemo() }
funccreateWork(id int)chanint { c := make(chanint) gofunc() { for { fmt.Printf("work %d,do %c\n", id, <-c) } }() return c } funcchanDemo() { var channels [10]chanint
for i := 0; i < 10; i++ { channels[i] =createWork(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) } funcmain() { chanDemo() }
funccreateWork(id int)chan<- int { c := make(chanint) gofunc() { for { fmt.Printf("work %d,do %c\n", id, <-c) } }() return c } funcchanDemo() { var channels [10]chan<- int
for i := 0; i < 10; i++ { channels[i] =createWork(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) } funcmain() { chanDemo() }
funcfinishSend() { c := make(chanint, 3) go work(0, c)
c <- 'a' c <- 'b' c <- 'c' close(c) time.Sleep(time.Millisecond) }
funcwork(id int, c chanint) { for { i,ok:= <-c if !ok{ //如果没有收到值,直接不接收数据了,因为此处是个死循环 break } fmt.Printf("work %d,do %c\n", id, i) } } //或者使用rang函数 funcwork(id int, c chanint) { for i := range c { fmt.Printf("work %d,do %c\n", id, i) } }
funcwork(id int, c chanint, done chanbool) { for i := range c { fmt.Printf("work %d,do %c\n", id, i) done <- true } } funccreateWork(id int) worker { w := worker{ in: make(chanint), done: make(chanbool), } go work(id, w.in, w.done) return w } funcchanDemo() { var workers [10]worker for i := 0; i < 10; i++ { workers[i] = createWork(i) } for i, worker := range workers { worker.in <- 'a' + i } for i, worker := range workers { worker.in <- 'A' + i } for _, worker := range workers { <-worker.done <-worker.done } //time.Sleep(time.Millisecond) }
type worker struct { in chanint wg *sync.WaitGroup }
funcwork(id int, c chanint,wg *sync.WaitGroup) { for i := range c { fmt.Printf("work %d,do %c\n", id, i) wg.Done() } } funccreateWork(id int,wg *sync.WaitGroup) worker { w := worker{ in: make(chanint), } go work(id, w.in,wg) return w } funcchanDemo() { var wg sync.WaitGroup var workers [10]worker for i := 0; i < 10; i++ { workers[i] = createWork(i,&wg) } for i, worker := range workers { worker.in <- 'a' + i wg.Add(1) }
for i, worker := range workers { worker.in <- 'A' + i wg.Add(1) }
funcmain() { var c1, c2 = generator(), generator() var worker = createWork(0) n := 0 var values []int //产生一个channel 到时间会送入一个值 //此处使用10s after := time.After(10 * time.Second) tick := time.Tick(time.Second) fmt.Println("开始时间:", time.Now()) 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 <-after: { fmt.Println("到时间结束:", time.Now()) return } //非阻塞 default: {
} }
} } funcwork(id int, c chanint) {
for i := range c { time.Sleep(time.Second) fmt.Printf("work %d,do %d\n", id, i) } } funccreateWork(id int)chan<- int { c := make(chanint) go work(id, c) return c } funcgenerator()chanint { out := make(chanint) gofunc() { i := 0 for { fmt.Println("生成数字", i) time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond) out <- i i++ } }() return out }
================== WARNING: DATA RACE Read at 0x00c000134008 by main goroutine: main.main() /Users/fuwei/work/goPros/go/learnGo/bytedance/ch46.mutex/main.go:25 +0xc5
Previous write at 0x00c000134008 by goroutine 7: main.(*atomicInt).increment() /Users/fuwei/work/goPros/go/learnGo/bytedance/ch46.mutex/main.go:11 +0x51 main.main.func1() /Users/fuwei/work/goPros/go/learnGo/bytedance/ch46.mutex/main.go:22 +0x32
Goroutine 7 (finished) created at: main.main() /Users/fuwei/work/goPros/go/learnGo/bytedance/ch46.mutex/main.go:21 +0xaa ================== 2 Found 1 data race(s) exit status 66
} } funcgetDirList(writer http.ResponseWriter, request *http.Request)error { dir_list, e := ioutil.ReadDir("./") if e != nil { fmt.Println("read dir error") return e }
for _, v := range dir_list { bytes := []byte(v.Name() + "\n") writer.Write(bytes) } return e } funcfileList(writer http.ResponseWriter, request *http.Request)error {