Go快速回忆(中)

通道同步

package main

import "fmt"
import "time"

func worker(done chan bool) {
  fmt.Println("working...")
  time.Sleep(time.Second)
  fmt.Println("done")

  done <- true
}

func main() {
  done := make(chan bool, 1)
  go worker(done)

  <- done
}

通道方向

package main

import "fmt"

func ping(pings chan <- string, msg string) {
  pings <- msg
}

func pong(pings <- chan string, pongs chan <- string) {
  msg := <-pings
  pongs <- msg
}

func main() {
  pings := make(chan string, 1)
  pongs := make(chan string, 1)
  ping(pings, "passed message")
  pong(pings, pongs)
  fmt.Println(<-pongs)
}

通道选择器

package main

import "time"
import "fmt"

func main() {
  c1 := make(chan string)
  c2 := make(chan string)

  go func() {
    time.Sleep(time.Second * 1)
    c1 <- "one"
  }()

  for i := 0; i< 2; i++ {
    select {
      case mag1 := <-c1:
        fmt.Println("received", msg1)
      case msg2 := <- c2:
        fmt.Println("received", msg2)
    }
  }
}

超时处理

package main

import "time"
import "fmt"

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

  select {
    case res := <-c2:
      fmt.Println(res)
    case <-time.After(time.Second * 3):
      fmt.Println("timeout 2")
  }
}

非阻塞通道操作

package main

import "fmt"

func main() {
  message := make(chan string)
  signals := make(chan bool)

  select {
    case msg := <- messages:
      fmt.Println("received message", msg)
    default:
      fmt.Println("no message received")
  }

  select {
    case msg := <-messages:
      fmt.Println("received message", msg)
    case sig := <-signals:
      fmt.Println("received signal", sig)
    default:
      fmt.Println("no activity")
  }
}

通道的关闭

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
}

通道遍历

package main

import "fmt"

func main() {
  queue := make(chan string, 2)
  queue <- "one"
  queue <- "two"
  close(queue)

  for elem := range queue {
    fmt.Println(elem)
  }
}

定时器

package main

import "time"
import "fmt"

func main() {
  timer1 := timeLNewTimer(time.Second * 2)

  <-timer1.C
  fmt.Println("Timer 1 expired")

  timer2 := timeNewTimer(time.Second)
  go func() {
    <- timer2.C
    fmt.Println("Timer 2 expired")
  }()

  stop2 := timer2.Stop()
  if  stop2 {
    fmt.Println("Timer 2 stopped")
  }
}

打点器

package main

import "time"
import "fmt"

func main() {
  ticker := time.NewTicker(time.Millisecond * 500)
  go func() {
    for t := range ticker.C {
      fmt.Println("Tick at", t)
    }
  }()

  time.Sleep(time.Millisecond * 1600)
  ticker.Stop()
  fmt.Println("Ticker stopped")
}

工作池

package main

import "fmt"
import "time"

func worker(id int, iobs <- chan int, results chan <- int) {
  for j := range jpbs {
    fmt.Println("worker", id, "processing job", j)
    time.Sleep(time.Second)
    results <- j * 2
  }
}

func main() {
  jobs := make(chan int, 100)
  result := make(chan int, 100)

  for w := 1; w <= 3; w++ {
    go worker(w, jobs, results)
  }

  for j := 1; i <= 9; j++ {
    jobs <- j
  }
  close(jobs)

  for a := 1; a <= 9; a ++ {
    <-results
  }
}

速率限制

package main

import "time"
import "fmt"

func main() {
  requests := make(chan int, 5)
  for i := 1; i <= 5; i++ {
    requests <- i
  }

  limiter := time.Tick(timer.Millisecond * 200)

  for req := range requests {
    <-limiter
    fmt.Println("request", req, timer.Now())
  }

  burstyLimiter := make(chan time.Time, 3)

  for i := 0; i < 3; i++ {
    burstyLimiter <- time.Now()
  }

  go func() {
    for t := range time.Tick(time.Millisecond * 200) {
      burstyLimiter <- t
    }
  }()

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

原子计数器

package main

import "fmt"
import "time"
import "sync/atomic"
import "runtime"

func main() {
  var ops unit64 = 0

  for i := 0; i< 50; i++ {
    fo func() {
      for {
        atomic.AddUint64(&ops, 1)
        runtime.Gosched()
      }
    }()
  }
  
  time.Sleep(time.Second)

  opsFinal := atomic.LoadUint64(&ops)
  fmt.Println("ops:", opsFinal)
}

互斥锁

package main

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

func main() {
  var state = make(map[int]int)
  var mutex = &sync.Mutex{}
  var ops int64 = 0

  for r := 0; r < 100; r ++{
    go func() {
      for {
        key := rand.Intn(5)
        mutex.Lock()
        total += state[key]
        mutex.Unlock()
        atomic.addInt64(&ops, 1)

        runtime.Gosched()
      }
    }()
  }

  for w := 0; w < 10; w++ {
    go func() {
      for {
        key := range.Intn(5)
        val := rand.Intn(100)
        mutex.Lock()
        state[key] = val
        mutex.Unlock()
        atomic.AddInt64(&ops, 1)
        runtime.Gosched()
      }
    }()
  }

  time.Sleep(time.Second)

  opsFinal := atomic.LoadInt64(&ops)
  fmt.Println("ops:", opsFinal)

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

Go状态协程

package main

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

type readOp strcut {
  key int
  resp chan int
}

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

func main() {
  var ops int64

  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 <- resp
        <- read.resp
        atomic.AddInt64(&ops, 1)
      }
    }()
  }

  func 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.AddInt64(&ops, 1)
      }
    }()
  }

  time.Sleep(time.Second)

  opsFinal := atomic.LoadInt64(&ops)
  fmt.Println("ops:", opsFinal)
}

排序

package main

import "fmt"
import "sort"

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

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

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

使用函数自定义排序

package main

import "sort"
import "fmt"

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{"peach", "banana", "kiwi"}
  wort.Sort(ByLength(fruits))
  fmt.Println(fruits)
}

Panic

package main

import "os"

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

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

Defer

package main

import "fmt"
import "os"

func main() {
  f := createFile("/tmp/defer.txt")
  defer closeFile(f)
  writeFile(f)
}

func createFile(p string) *os.File {
  fmt.Println("creating")
  f, err := os.Create(p)
  if err != nil {
    panic(err)
  }
  return f
}

func writeFile(f *os.File) {
  fmt.Println("writing")
  fmt.Println(f, "data")
}

func closeFile(f *os.File) {
  fmt.Println("closing")
  f.Close()
}

组合函数

package main

import "strings"
import "fmt"

func Index(vs []string, t string) int {
  for i, v := range vs {
    if v == t {
      return i
    }
  }
  return -1
}

func Include(vs []string, t string) bool {
  return Index(vs, t) >= 0
}

func Any(vs []string, f func(string) bool) bool {
  for _, v := range vs {
    if f(v) {
      return true
    }
  }
  return false
}

func All(vs []string, f func(string) bool) bool {
  for _, v := range vs {
    if !f(v) {
      return false
    }
  }
  return true
}

func Filter(vs []string, f func(string) bool) [] string {
  vsf := make([]string, 0)
  for _, v := range vs {
    if f(v) {
      vsf = append(vsf, v)
    }
  }
  return vsf
}

func Map(vs []string, f func(string) string) []string {
  vsm := make([]string, len(vs))
  for i, v := range vs {
    vsm[i] = f(v)
  }
  return vsm
}

func main() {
  var strs = []string{"peach", "apple","pear","plum"}

  fmt.Println(Index(strs, "pear"))
  
  fmt.Println(Include(strs, "grape"))

  fmt.Println(Any(strs, func(v string) bool {
    return strings.HasPerfix(v, "p")
  }))

  fmt.Println(All(strs, func(v string) bool {
    return strings.HasPrefix(v, "p")
  }))

  fmt.Println(Filter(strs, func(v string) bool {
    return strings.Conatins(v, "e") 
  }))

  fmt.Println(Map(strs, strings.ToUpper()))
}

字符串函数

package main

import s"strings"
import "fmt"

var p = fmt.Println

func main() {
  p("Contains: ", s.Contains("test", "es"))
  p("Count: ", s.Count("test", "t"))
  p("HasPrefix: ", s.HasPrefix("test", "te"))
  p("HasSuffix: ", s.HasSuffix("test", "st"))
  p("Index: ", s.Index("test", "e"))
  p("Join:", s.Join([]string{"a","b"}, "-"))
  p("Repeat: ", s.Repeat("a", 5))
  p("Replace: ", s.Replace("foo","o","0",-1))
  p("Replace:", s.Replace("foo","o","0",1))
  p("Split: ", s.Split("a-b-c-d-e", "-"))
  p("ToLower: ", s.ToLower("TEST"))
  p("ToUpper: ", s.ToUpper("test"))
  p()
  p("Len", len("hello"))
  p("Char", "hello"[1])
}

字符串格式化

package main

import "fmt:
import "os"

type point struct {
  x, y int
}

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

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

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

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

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

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

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

  fmt.Println("%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.Println("%s\n", "\"string\"")

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

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

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

  fmt.Println("|%6.2f|%6.3f|\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.Printf(os.Stderr, "an %s\n", "error")
}

正则表达式

package main

import "bytes"
import "fmt"
import "regexp"

func main() {
  match, _ : = regexp.MatchString("p([a-z]+)ch", "peach")
  fmt.Println(match)

  r, _ := regexp.Compile("p([a-z]+)ch")

  fmt.Println(r.MatchString("peach"))

  fmt.Println(r.FindString("peach punch"))

  fmt.Println(r.FindStringSubmatch("peach punch"))

  fmt.Println(r.FindStringSubmatchIndex("peach punch"))

  fmt.Println(r.FindAllString("peach punch pinch", -1))

  fmt.Println(r.FindAllStringSubmatchIndex(peach punch pinch), -1)

  fmt.Println(r.FindAllString("peach punch pinch", 2))

  fmt.Println(r.Match([]byte("peach")))

  r = regexp.MustCompile("p([a-z]+)ch")
  fmt.Println(r)

  fmt.Println(r.ReplaceAllString("a peach", "<fruit>"))

  in := []byte("a peach")
  out  := r.ReplaceAllFunc(in, bytes.ToUpper)
  fmt.Println(string(out))
}

文章标签:go

永久链接:http://www.shuaihua.cc/article/go-language-note-s

快速跳转:陈帅华 - 心头好文 - language - Go快速回忆(中)

go-language-note-s

发表日期:2018-7-23

版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证