Go channel: использовать данные из канала, но ничего не передавать на канал - PullRequest
0 голосов
/ 19 января 2019

Например, у меня есть этот код:

package main

import (
    "fmt"
)

func main() {

    c1 := make(chan interface{})
    close(c1)
    c2 := make(chan interface{})
    close(c2)

    var c1Count, c2Count int
    for i := 1000; i >= 0; i-- {
        select {
        case <-c1:
            c1Count++
        case <-c2:
            c2Count++
        }

    }
    fmt.Printf("c1Count: %d\nc2Count: %d\n  ", c1Count, c2Count)
}

Во время работы вывод будет:

c1Count: 513
c2Count: 488

Не знаю, что мы создаем: c1 и c2канал ничего не делая.Почему в блоке select / case c1Count и c2Count могут увеличивать значение?

Спасибо

1 Ответ

0 голосов
/ 19 января 2019

Спецификация языка программирования Go

Закрыть

После вызова close и после любых ранее отправленных значений Операции получения вернут нулевое значение для Тип канала без блокировки. Многозначная операция получения возвращает полученное значение вместе с указанием того, канал закрыт.


Вы считаете нулевые значения.

Например,

package main

import (
    "fmt"
)

func main() {

    c1 := make(chan interface{})
    close(c1)
    c2 := make(chan interface{})
    close(c2)

    var c1Count, c2Count int
    var z1Count, z2Count int
    for i := 1000; i >= 0; i-- {
        select {
        case z1 := <-c1:
            c1Count++
            if z1 == nil {
                z1Count++
            }

        case z2 := <-c2:
            c2Count++
            if z2 == nil {
                z2Count++
            }
        }

    }
    fmt.Printf("c1Count: %d\nc2Count: %d\n", c1Count, c2Count)
    fmt.Printf("z1Count: %d\nz2Count: %d\n", z1Count, z2Count)
}

Детская площадка: https://play.golang.org/p/tPRkqXrAFno

Выход:

c1Count: 511
c2Count: 490
z1Count: 511
z2Count: 490

Спецификация языка программирования Go

Для выписок

Для операторов с предложением диапазона

Для каналов полученные значения итерации являются последовательными значениями отправляется на канал, пока канал не будет закрыт. Если канал ноль, выражение диапазона блокируется навсегда.

Close полезен для оператора for с предложением range.

...