Go语言学习 Day04 Summary part2

1. Timeouts

Timeouts are important for programs that connect to external resources or that otherwise need to bound execution time. Implementing timeouts in Go is easy and elegant thanks to channels and select.

[maxwell@oracle-db-19c Day04]$ vim timeouts.go
[maxwell@oracle-db-19c Day04]$ cat timeouts.go 
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")
    }
}
[maxwell@oracle-db-19c Day04]$ go run timeouts.go
timeout 1
result 2
[maxwell@oracle-db-19c Day04]$ 

 2.Non-Blocking Channel Operations

Basic sends and receives on channels are blocking. However, we can use select with a default clause to implement non-blocking sends, receives, and even non-blocking multi-way selects.

[maxwell@oracle-db-19c Day04]$ vim non_blocking_channel_operations.go
[maxwell@oracle-db-19c Day04]$ cat non_blocking_channel_operations.go      
package main

import "fmt"

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

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

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

    select {
    case msg := <-messages:
         fmt.Println("received message", msg)
    case sig := <-signals:
         fmt.Println("received signal", sig)
    default:
        fmt.Println("no activity")
    }
}
[maxwell@oracle-db-19c Day04]$ go run non_blocking_channel_operations.go
no message received
no message sent
no activity
[maxwell@oracle-db-19c Day04]$ 

3.Closing Channels

Closing a channel indicates that no more values will be sent on it. This can be useful to communicate completion to the channel’s receivers.

[maxwell@oracle-db-19c Day04]$ vim closing_channels.go
[maxwell@oracle-db-19c Day04]$ cat closing_channels.go
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
}
[maxwell@oracle-db-19c Day04]$ go run closing_channels.go
sent job 1
sent job 2
sent job 3
sent all jobs
received job 1
received job 2
received job 3
received all jobs
[maxwell@oracle-db-19c Day04]$ 

4.Range over Channels

how for and range provide iteration over basic data structures. We can also use this syntax to iterate over values received from a channel.

[maxwell@oracle-db-19c Day04]$ vim range_over_channels.go
[maxwell@oracle-db-19c Day04]$ cat range_over_channels.go 
package main

import "fmt"

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

    for elem := range queue{
        fmt.Println(elem)
    }
}
[maxwell@oracle-db-19c Day04]$ go run range_over_channels.go
one
two
[maxwell@oracle-db-19c Day04]$

5.Timers

We often want to execute Go code at some point in the future, or repeatedly at some interval. Go’s built-in timer and ticker features make both of these tasks easy. We’ll look first at timers and then at tickers.

[maxwell@oracle-db-19c Day04]$ vim timers.go   
[maxwell@oracle-db-19c Day04]$ cat timers.go   
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)
}
[maxwell@oracle-db-19c Day04]$ go run timers.go
Timer 1 fired
Timer 2 stopped
[maxwell@oracle-db-19c Day04]$ 

你可能感兴趣的:(Go,by,Example,golang,学习,oracle)