Go13-goExamples2

210 阅读4分钟

1、Timeouts 超时

package main

import (
   "fmt"
   "time"
)

func main()  {
   c1:=make(chan string,1)
   go func() {
      time.Sleep(2*time.Second)
      c1<-"result 1"
   }()

   select {
   case res:=<-c1:
      fmt.Println(res)
   case <-time.After(1*time.Second):
      fmt.Println("timeout 1")
   }
   c2:=make(chan string,1)
   go func() {
      time.Sleep(2*time.Second)
      c2<-"result 2"
   }()
   select {
   case res:=<-c2:
      fmt.Println(res)
   case <-time.After(3*time.Second):
      fmt.Println("timeout 2")
   }
}
/*
timeout 1
result 2
*/

2、Non-Blocking Channel Operations 非阻塞通道

通道中被阻塞,我们使用select来实现非阻塞发送。

package main 

import "fmt"

func main(){
    jobs:=make(chan int,5)
    done:=make(chan bool)
    
    go func(){
        for{
            j,more:=<-jobs
            if more{
                fmt.Println("received job",j)
            }else{
                fmt.Println("received all jobs")
                done<-true
                return 
            }
        }
    }
    
    for j:=1;j<=3;j++{
        jobs<-j
        fmt.Println("sent job",j)
    }
    close(jobs)
    fmt.Println("sent all jobs")
    <-done
}
/*

*/

3、closing channels 关闭通道

package main

import "fmt"

func main()  {
   jobs:=make(chan int,5)
   done:=make(chan bool)

   go func() {
      for  {
         j,more:=<-jobs
         if more{
            fmt.Println("received job",j)
         }else{
            fmt.Println("received all job")
            done<-true
            return
         }
      }
   }()

   for j:=0;j<=3;j++ {
      jobs<-j
      fmt.Println("sent job",j)
   }
   close(jobs)
   fmt.Println("sent all jobs")
   <-done
}
/*
sent job 0
received job 0
received job 1
sent job 1
sent job 2
sent job 3
sent all jobs
received job 2
received job 3
received all job

Process finished with the exit code 0


*/

4、Range over Channels

通过range 来遍历channels

package main

import "fmt"

func main(){
    queue:=make(chan string,2)
    queue<-"one"
    queue<-"two"
    close(queue)
    
    for elem:=range queue{
        fmt.Println(elem)
    }
}
/*
one
two
*/

5、timer

package main

import (
   "fmt"
   "time"
)

func main()  {
   timer1:=time.NewTimer(2*time.Second)
   <-timer1.C
   fmt.Println("timer 1 fired")
   timer2:=time.NewTimer(time.Second)
   go func() {
      <-timer2.C
      fmt.Println("Timer 2 fired")
   }()
   stop2:=timer2.Stop()
   if stop2{
      fmt.Println("timer 2 stopped")
   }
   time.Sleep(2*time.Second)
}

/*
timer 1 fired
timer 2 stopped
*/

6、Tickers

package main

import (
   "fmt"
   "time"
)

func main()  {
   ticker:=time.NewTicker(500*time.Millisecond)
   done:=make(chan bool)

   go func() {
      for  {
         select {
         case <-done:
            return
         case t:=<-ticker.C:
            fmt.Println("ticker at",t)
         }
      }
   }()

   time.Sleep(1600*time.Millisecond)
   ticker.Stop()
   done<-true
   fmt.Println("Ticker stopped")
}
/*
ticker at 2021-07-30 15:20:32.8857464 +0800 CST m=+0.508700601
ticker at 2021-07-30 15:20:33.3872252 +0800 CST m=+1.010179401
ticker at 2021-07-30 15:20:33.8872464 +0800 CST m=+1.510200601
Ticker stopped
*/

6、worker pools 工作池

package main

import (
   "fmt"
   "time"
)

func Worker(id int,jobs <-chan int,result chan<-int)  {
   for j:=range jobs{
      fmt.Println("worker",id,"started job",j)
      time.Sleep(time.Second)
      fmt.Println("worker",id,"finished job",j)
      result<-j*2
   }
}


func main()  {
   const numJobs =5
   jobs:=make(chan int,numJobs)
   results:=make(chan int,numJobs)
   
   for w:=1;w<=3;w++{
      go Worker(w,jobs,results)
   }
   for j:=1;j<=numJobs;j++{
      jobs<-j
   }
   close(jobs)
   
   for a:=1;a<=numJobs;a++{
      <-results
   }
}

7、WaitGroups 等待组

package main

import (
   "fmt"
   "sync"
   "time"
)

func work(id int,wg *sync.WaitGroup)  {
   defer wg.Done()
   fmt.Printf("worker %d starting\n",id)
   time.Sleep(time.Second)
   fmt.Printf("worker %d done\n",id)
}


func main()  {
   var wg sync.WaitGroup

   for i:=1;i<=5;i++{
      wg.Add(1)
      go work(i,&wg)
   }
   wg.Wait()
}

8、Rate Limiting

package main

import (
   "fmt"
   "time"
)

func main()  {
   requests:=make(chan int,5)

   for i:=1;i<=5;i++{
      requests<-i
   }
   close(requests)
   limiter:=time.Tick(200*time.Millisecond)

   for req:=range requests{
      <-limiter
      fmt.Println("request",req,time.Now())
   }
   burstyLimiter:=make(chan time.Time,3)

   for i:=0;i<3;i++{
      burstyLimiter<-time.Now()
   }
   go func() {
      for t:=range time.Tick(200*time.Millisecond){
         burstyLimiter<-t
      }
   }()

   burstyRequest:=make(chan int,5)
   for i:=1;i<=5;i++{
      burstyRequest<-i
   }
   close(burstyRequest)
   for req:=range burstyRequest{
      <-burstyLimiter
      fmt.Println("request",req,time.Now())
   }
}

9、Atimic Counters 原子计数器

package main

import (
   "fmt"
   "sync"
   "sync/atomic"
)

func main()  {
   var ops uint 64

   var wg sync.WaitGroup

   for i:=0;i<50;i++{
      wg.Add(1)
      go func() {
         for c:=0;c<1000;c++{
            atomic.AddUint64(&ops,1)
         }
         wg.Done()
      }()
   }
   wg.Wait()
   fmt.Println("ops:",ops)
}

10、Mutexes 互斥器

package main

import (
   "fmt"
   "math/rand"
   "sync"
   "sync/atomic"
   "time"
)

func main() {

   var state = make(map[int]int)

   var mutex = &sync.Mutex{}

   var readOps uint64
   var writeOps uint64

   for r := 0; r < 100; r++ {
      go func() {
         total := 0
         for {

            key := rand.Intn(5)
            mutex.Lock()
            total += state[key]
            mutex.Unlock()
            atomic.AddUint64(&readOps, 1)

            time.Sleep(time.Millisecond)
         }
      }()
   }

   for w := 0; w < 10; w++ {
      go func() {
         for {
            key := rand.Intn(5)
            val := rand.Intn(100)
            mutex.Lock()
            state[key] = val
            mutex.Unlock()
            atomic.AddUint64(&writeOps, 1)
            time.Sleep(time.Millisecond)
         }
      }()
   }

   time.Sleep(time.Second)

   readOpsFinal := atomic.LoadUint64(&readOps)
   fmt.Println("readOps:", readOpsFinal)
   writeOpsFinal := atomic.LoadUint64(&writeOps)
   fmt.Println("writeOps:", writeOpsFinal)

   mutex.Lock()
   fmt.Println("state:", state)
   mutex.Unlock()
}

11、Stateful Goroutines有状态的协程

package main

import (
    "fmt"
    "math/rand"
    "sync/atomic"
    "time"
)

type readOp struct {
    key  int
    resp chan int
}
type writeOp struct {
    key  int
    val  int
    resp chan bool
}

func main() {

    var readOps uint64
    var writeOps uint64

    reads := make(chan readOp)
    writes := make(chan writeOp)

    go func() {
        var state = make(map[int]int)
        for {
            select {
            case read := <-reads:
                read.resp <- state[read.key]
            case write := <-writes:
                state[write.key] = write.val
                write.resp <- true
            }
        }
    }()

    for r := 0; r < 100; r++ {
        go func() {
            for {
                read := readOp{
                    key:  rand.Intn(5),
                    resp: make(chan int)}
                reads <- read
                <-read.resp
                atomic.AddUint64(&readOps, 1)
                time.Sleep(time.Millisecond)
            }
        }()
    }

    for w := 0; w < 10; w++ {
        go func() {
            for {
                write := writeOp{
                    key:  rand.Intn(5),
                    val:  rand.Intn(100),
                    resp: make(chan bool)}
                writes <- write
                <-write.resp
                atomic.AddUint64(&writeOps, 1)
                time.Sleep(time.Millisecond)
            }
        }()
    }

    time.Sleep(time.Second)

    readOpsFinal := atomic.LoadUint64(&readOps)
    fmt.Println("readOps:", readOpsFinal)
    writeOpsFinal := atomic.LoadUint64(&writeOps)
    fmt.Println("writeOps:", writeOpsFinal)
}

12、Sorting

package main

import (
   "fmt"
   "sort"
)

func main()  {
   str:=[] string{"c","a","b"}
   sort.Strings(str)

   fmt.Println("string",str)

   ints:=[] int {7,2,4}
   sort.Ints(ints)

   fmt.Println("Ints",ints)

   s:=sort.IntsAreSorted(ints)
   fmt.Println("Sorted",s)
   
}

13、SortingByFunctions 通过函数排序

go 中的排序算法用的快排,当max<11时用的堆排,总体来说是快排结合堆排

package main

import (
   "fmt"
   "sort"
)

type byLength [] string

func (s byLength) Len() int {
   return len(s)
}

func (s byLength) Swap(i,j int)  {
   s[i],s[j]=s[j],s[i]
}

func (s byLength) Less(i,j int)bool  {
   return len(s[i])<len(s[j])
}

func main()  {
   fruits:=[]string{"perch","banna","kiwi"}
   sort.Sort(byLength(fruits))
   fmt.Println(fruits)
}

14、panic

用来判定潜在的错误,通常我们用panic来表示程序正常运行不应该出现的错误。

package main

import "os"

func main()  {
   panic("a problem")

   _,err:=os.Create("/tmp/file")
   if err!=nil{
      panic(err)
   }
}
/*
panic: a problem
*/

15、defer 延迟

package main

import "fmt"

func main()  {
   defer fmt.Println("1")
   defer fmt.Println("2")
   defer fmt.Println("3")
   fmt.Println("4")
}

返回 4 3 2 1

15、stringFunc 字符串函数

package main

import (
   "fmt"
   "strings"
)

var p=fmt.Println
func main()  {
   p("contains:",strings.Contains("test","es"))
   p("count:",strings.Count("trst","t"))
   p("hasPrefix:",strings.HasSuffix("test","te"))
   p("index:",strings.Index("test","e"))
   p("join:",strings.Join([]string{"a","b"},"."))
   p("Repeat:",strings.Repeat("a",5))
   p("Split:",strings.Split("a-b-c-d-e","-"))
   p("ToLower:",strings.ToLower("StringS"))
   p("Toupper:",strings.ToUpper("StringS"))
   p()
   p("len:",len("hello"))
   p("char","hello"[1])
}

16、String Formatting 字符串格式


package main

import (
"fmt"
"os"
)

type point struct {
   x, y int
}

func main() {

   p := point{1, 2}
   fmt.Printf("%v\n", p)

   fmt.Printf("%+v\n", p)

   fmt.Printf("%#v\n", p)

   fmt.Printf("%T\n", p)

   fmt.Printf("%t\n", true)

   fmt.Printf("%d\n", 123)

   fmt.Printf("%b\n", 14)

   fmt.Printf("%c\n", 33)

   fmt.Printf("%x\n", 456)

   fmt.Printf("%f\n", 78.9)

   fmt.Printf("%e\n", 123400000.0)
   fmt.Printf("%E\n", 123400000.0)

   fmt.Printf("%s\n", ""string"")

   fmt.Printf("%q\n", ""string"")

   fmt.Printf("%x\n", "hex this")

   fmt.Printf("%p\n", &p)

   fmt.Printf("|%6d|%6d|\n", 12, 345)

   fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45)

   fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45)

   fmt.Printf("|%6s|%6s|\n", "foo", "b")

   fmt.Printf("|%-6s|%-6s|\n", "foo", "b")

   s := fmt.Sprintf("a %s", "string")
   fmt.Println(s)

   fmt.Fprintf(os.Stderr, "an %s\n", "error")
}

17、正则表达式 略