我可以重新打开一个封闭的频道吗?

I am trying to figure out whether I can reopen a channel after closing it.

Test case:

  1. I have a channel with some things in it
  2. I want to range over them therefore I need to close the channel beforehand
  3. I want to put more stuff in the channel and iterate through it once more
go func() {
    queue <- "1"
    queue <- "2"
    close(queue)
}()

for i := range queue {
    go func(i string) {
        fmt.Println("From queue: ", i)
    }(i)
}

go func() {
    open(queue)
    queue <- "3"
    queue <- "4"
    close(queue)
}()

for i := range queue {
    go func(i string) {
        fmt.Println("From queue: ", i)
    }(i)
}
  • Of course open does not exist. How can I implement something like what I need in Go?
  • I don't want to use the Sleep function

You cannot reopen a closed channel but you can send a channel on a channel, perhaps this is what you're looking for?

package main

import (
    "fmt"
    "time"
)

func main() {
    queue := make(chan chan int)
    defer close(queue)

    go func() { // reader
        for {
            ch := <-queue
            for i := range ch {
                fmt.Println(i)
            }
            fmt.Println("Done with this channel")
        }
    }()

    go func() { // writer-1
        ch := make(chan int)
        defer close(ch)
        queue <- ch
        ch <- 4
        ch <- 2
    }()

    go func() { // writer-2
        ch := make(chan int)
        defer close(ch)
        queue <- ch
        ch <- 4
        ch <- 20
    }()
    time.Sleep(time.Second)
}

I want to range over them therefore I need to close the channel beforehand

Nope, no need to close the channel. It'll resume iteration when another item is pushed thru the channel.

The below code accepts console input and pushes it to the channel:

main.go

package main

import (
    "log"
    "bufio"
    "os"
    "fmt"
)

func process(c chan string) {
    for s := range c {
        log.Println("processed", s)
    }
}

func main() {
    c := make(chan string, 10)
    go process(c)

    // get from console and process
    reader := bufio.NewReader(os.Stdin)
    fmt.Println("INPUT STUFF. TYPE #quit TO EXIT.")
    for {
        input, _, _ := reader.ReadLine()
        if string(input) == "#quit" {
            break
        }
        c <- string(input)
    }

    log.Println("BYE!")
}

output

INPUT STUFF. TYPE #quit TO EXIT.
hello
2018/10/23 10:43:52 processed hello
world
2018/10/23 10:43:54 processed world
#quit
2018/10/23 10:43:57 BYE!

The below sample uses Sleep() and is runnable as a Go Playground snippet

package main

import (
    "log"
    "time"
)

func process(c chan string) {
    for s := range c {
        log.Println("processed", s)
    }
}

func main() {
    c := make(chan string, 10)

    go process(c)

    // push some data
    c <- "barry allen"
    c <- "iris west"

    time.Sleep(time.Second * 2)

    // push more data
    c <- "joe west"
    c <- "caitlin snow"

    time.Sleep(time.Second * 3)
}

output

2009/11/10 23:00:00 processed barry allen
2009/11/10 23:00:00 processed iris west
2009/11/10 23:00:02 processed joe west
2009/11/10 23:00:02 processed caitlin snow

Hope this helps. Cheers,