select详解

2020-07-05  本文已影响0人  只争朝夕々

语法具体定义参考官方定义

https://golang.org/ref/spec#Select_statements

select语句执行分以下一个步骤执行

案例分析

所有channel表达式都会被求值、所有被发送的表达式都会被求值。求值顺序:自上而下、从左到右

func main() {
    var ch1 chan int
    var ch2 chan int
    var chs = []chan int{ch1, ch2}
    var numbers = []int{1, 2, 3, 4, 5}

    getNumber := func(i int) int {
        fmt.Printf("numbers[%d]\n", i)
        return numbers[i]
    }

    getChan := func(i int) chan int {
        fmt.Printf("chs[%d]\n", i)
        return chs[i]
    }

    select {
    case getChan(0) <- getNumber(2):
        fmt.Println("1th case is selected.")
    case getChan(1) <- getNumber(3):
        fmt.Println("2th case is selected.")
    default:
        fmt.Println("default case")
    }
}

输出:

chs[0]
numbers[2]
chs[1]
numbers[3]
default case

Process finished with exit code 0

如果有一个或多个通信操作可以完成,则Go运行时系统会伪随机的选择一个执行。否则,如果有default分支,则执行default分支语句,如果连default都没有,则select语句会一直阻塞,直到至少有一个通信操作可以进行

func main() {
    start := time.Now()
    ch1 := make(chan int)
    ch2 := make(chan int)

        go func() {
        time.Sleep(2 * time.Second)
        ch1 <- 3
    }()

    go func() {
        time.Sleep(3 * time.Second)
        ch2 <- 5
    }()

    fmt.Println("blocking on read...")

    select {
    case <-ch1:
        fmt.Printf("ch1 case...")
    case <-ch2:
        fmt.Printf("ch2 case...")
    default:
        fmt.Printf("default case...")
    }
}

输出:

blocking on read...
default case...
Process finished with exit code 0
func main() {
    start := time.Now()
        ch1 := make(chan int)
    ch2 := make(chan int)

    go func() {
        time.Sleep(2 * time.Second)
        ch1 <- 3
    }()

    go func() {
        time.Sleep(3 * time.Second)
        ch2 <- 5
    }()

    fmt.Println("blocking on read...")

    select {
    case <-ch1:
        fmt.Printf("ch1 case...")
    case <-ch2:
        fmt.Printf("ch2 case...")
    }
}

输出:

blocking on read...
ch1 case...
Process finished with exit code 0
func main() {
    start := time.Now()
    ch1 := make(chan int)
    ch2 := make(chan int)

    go func() {
        time.Sleep(1 * time.Second)
        ch1 <- 3
    }()

    go func() {
        time.Sleep(1 * time.Second)
        ch2 <- 5
    }()

    fmt.Println("blocking on read...")

    select {
    case <-ch1:
        fmt.Printf("ch1 case...")
    case <-ch2:
        fmt.Printf("ch2 case...")
    }
}

输出:

blocking on read...
ch1 case...
Process finished with exit code 0
blocking on read...
ch2 case...
Process finished with exit code 0
上一篇下一篇

猜你喜欢

热点阅读